def make_options_menu(self, b):
     wi = b.wi
     b.visible = False
     b.name.visible = False
     b.load.visible = False
     actions = [('Enumerate Phenotypes', self.enumerate_phenotypes_menu),
                ('Analyze Case', self.case_report_menu),
                ('Intersect Phenotypes', self.case_intersect_menu),
                ('Co-localize Phenotypes', self.co_localize_menu),
                ('Create Plot', self.create_plot_menu)]
     actions_h = HTML(value='<b>Actions</b>')
     options_h = HTML(value='<b>Options</b>')
     options = [('Edit Symbols', self.create_edit_symbols),
                ('Edit Parameters', self.create_edit_parameters),
                ('Save Data', self.save_widget_data)]
     actions_w = Tab()
     options_w = []
     for name, method in options:
         button = Button(description=name)
         button.on_click(method)
         ## button.version = b.version
         if method is None:
             button.disabled = True
         options_w.append(button)
     edit = Button(description='Modify System')
     edit.on_click(self.modify_equations_widget)
     warning = HTML()
     warning.value = '<font color="red"><b>Warning! Modifying system erases saved figures and tables.</b></font>'
     wi.children = [actions_h, actions_w] + [options_h] + options_w + [edit, warning]
     for title, method in actions:
         title, widget = method(self)
         children = [i for i in actions_w.children] + [widget]
         actions_w.children = children
         actions_w.set_title(len(children)-1, title)
     self.widget.selected_index = 1
 def modify_equations_widget(self, b):
     self.ds = None
     self.figure_data = []
     self.table_data = []
     self.widget.close()
     self.widget = Tab()
     display(self.root)   
     self.update_child('Main Menu', self.edit_equations_widget(editing=True))
 def reload_widgets(self):
     self.widget = Tab()
     display(self.root)
     self.update_child('Main Menu', self.edit_equations_widget())
     if self.ds is None:
         return
     self.update_widgets()
     self.figures.load_widgets()
Exemple #4
0
def visualize_images(images, figure_size=(7, 7), popup=False, **kwargs):
    r"""
    Widget that allows browsing through a list of images.

    Parameters
    -----------
    images : `list` of :map:`Image` or subclass
        The list of images to be displayed. Note that the images can have
        different attributes between them, i.e. different landmark groups and
        labels, different number of channels etc.

    figure_size : (`int`, `int`), optional
        The initial size of the plotted figures.

    popup : `boolean`, optional
        If enabled, the widget will appear as a popup window.

    kwargs : `dict`, optional
        Passed through to the viewer.
    """
    from menpo.image import MaskedImage
    import matplotlib.pyplot as plt

    # make sure that images is a list even with one image member
    if not isinstance(images, Sized):
        images = [images]

    # find number of images
    n_images = len(images)

    # find initial groups and labels that will be passed to the landmark options
    # widget creation
    first_has_landmarks = images[0].landmarks.n_groups != 0
    if first_has_landmarks:
        initial_groups_keys, initial_labels_keys = \
            _extract_groups_labels(images[0])
    else:
        initial_groups_keys = [' ']
        initial_labels_keys = [[' ']]

    # define plot function
    def plot_function(name, value):
        # clear current figure, but wait until the new data to be displayed are
        # generated
        clear_output(wait=True)

        # get selected image number
        im = 0
        if n_images > 1:
            im = image_number_wid.selected_index

        # update info text widget
        image_has_landmarks = images[im].landmarks.n_groups != 0
        image_is_masked = isinstance(images[im], MaskedImage)
        update_info(images[im], image_is_masked, image_has_landmarks,
                    landmark_options_wid.group)

        # get the current figure id
        figure_id = save_figure_wid.figure_id

        # show image with selected options
        new_figure_id = _plot_figure(
            image=images[im], figure_id=figure_id, image_enabled=True,
            landmarks_enabled=landmark_options_wid.landmarks_enabled,
            image_is_masked=channel_options_wid.image_is_masked,
            masked_enabled=(channel_options_wid.masked_enabled and
                            image_is_masked),
            channels=channel_options_wid.channels,
            glyph_enabled=channel_options_wid.glyph_enabled,
            glyph_block_size=channel_options_wid.glyph_block_size,
            glyph_use_negative=channel_options_wid.glyph_use_negative,
            sum_enabled=channel_options_wid.sum_enabled,
            groups=[landmark_options_wid.group],
            with_labels=[landmark_options_wid.with_labels],
            groups_colours=dict(), subplots_enabled=False,
            subplots_titles=dict(), image_axes_mode=True,
            legend_enabled=landmark_options_wid.legend_enabled,
            numbering_enabled=landmark_options_wid.numbering_enabled,
            x_scale=figure_options_wid.x_scale,
            y_scale=figure_options_wid.x_scale,
            axes_visible=figure_options_wid.axes_visible,
            figure_size=figure_size, **kwargs)

        # save the current figure id
        save_figure_wid.figure_id = new_figure_id

    # define function that updates info text
    def update_info(image, image_is_masked, image_has_landmarks, group):
        # Prepare masked (or non-masked) string
        masked_str = 'Masked Image' if image_is_masked else 'Image'
        # Display masked pixels if image is masked
        masked_pixels_str = (r'{} masked pixels (attached mask {:.1%} true)'.
                             format(image.n_true_pixels(),
                                    image.mask.proportion_true())
                             if image_is_masked else '')
        # Display number of landmarks if image is landmarked
        landmarks_str = (r'{} landmark points.'.
                         format(image.landmarks[group].lms.n_points)
                         if image_has_landmarks else '')
        path_str = image.path if hasattr(image, 'path') else 'NO PATH'

        # Create info string
        info_txt = r"""
             {} of size {} with {} channel{}
             {}
             {}
             min={:.3f}, max={:.3f}
             {}
        """.format(masked_str, image._str_shape, image.n_channels,
                   's' * (image.n_channels > 1), path_str, masked_pixels_str,
                   image.pixels.min(), image.pixels.max(), landmarks_str)

        # update info widget text
        info_wid.children[1].value = _raw_info_string_to_latex(info_txt)

    # create options widgets
    channel_options_wid = channel_options(images[0].n_channels,
                                          isinstance(images[0], MaskedImage),
                                          plot_function,
                                          masked_default=False,
                                          toggle_show_default=True,
                                          toggle_show_visible=False)
    # The landmarks checkbox default value if the first image doesn't have
    # landmarks
    landmark_options_wid = landmark_options(
        initial_groups_keys, initial_labels_keys, plot_function,
        toggle_show_default=True, landmarks_default=first_has_landmarks,
        legend_default=True, numbering_default=False, toggle_show_visible=False)
    # if only a single image is passed in and it doesn't have landmarks, then
    # landmarks checkbox should be disabled
    landmark_options_wid.children[1].children[0].disabled = \
        not first_has_landmarks
    figure_options_wid = figure_options(plot_function, scale_default=1.,
                                        show_axes_default=False,
                                        toggle_show_default=True,
                                        figure_scale_bounds=(0.1, 2),
                                        figure_scale_step=0.1,
                                        figure_scale_visible=True,
                                        toggle_show_visible=False)
    info_wid = info_print(toggle_show_default=True,
                          toggle_show_visible=False)
    initial_figure_id = plt.figure()
    save_figure_wid = save_figure_options(initial_figure_id,
                                          toggle_show_default=True,
                                          toggle_show_visible=False)

    # define function that updates options' widgets state
    def update_widgets(name, value):
        # get new groups and labels, update landmark options and format them
        group_keys, labels_keys = _extract_groups_labels(images[value])
        update_landmark_options(landmark_options_wid, group_keys,
                                labels_keys, plot_function)
        format_landmark_options(landmark_options_wid, container_padding='6px',
                                container_margin='6px',
                                container_border='1px solid black',
                                toggle_button_font_weight='bold',
                                border_visible=False)

        # update channel options
        update_channel_options(channel_options_wid,
                               n_channels=images[value].n_channels,
                               image_is_masked=isinstance(images[value],
                                                          MaskedImage))

    # create final widget
    if n_images > 1:
        # image selection slider
        image_number_wid = animation_options(
            index_min_val=0, index_max_val=n_images-1,
            plot_function=plot_function, update_function=update_widgets,
            index_step=1, index_default=0,
            index_description='Image Number', index_minus_description='<',
            index_plus_description='>', index_style='buttons',
            index_text_editable=True, loop_default=True, interval_default=0.3,
            toggle_show_title='Image Options', toggle_show_default=True,
            toggle_show_visible=False)

        # final widget
        cont_wid = TabWidget(children=[info_wid, channel_options_wid,
                                       landmark_options_wid,
                                       figure_options_wid, save_figure_wid])
        wid = ContainerWidget(children=[image_number_wid, cont_wid])
        button_title = 'Images Menu'
    else:
        # final widget
        wid = TabWidget(children=[info_wid, channel_options_wid,
                                  landmark_options_wid, figure_options_wid,
                                  save_figure_wid])
        button_title = 'Image Menu'
    # create popup widget if asked
    if popup:
        wid = PopupWidget(children=[wid], button_text=button_title)

    # display final widget
    display(wid)

    # set final tab titles
    tab_titles = ['Image info', 'Channels options', 'Landmarks options',
                  'Figure options', 'Save figure']
    if popup:
        if n_images > 1:
            for (k, tl) in enumerate(tab_titles):
                wid.children[0].children[1].set_title(k, tl)
        else:
            for (k, tl) in enumerate(tab_titles):
                wid.children[0].set_title(k, tl)
    else:
        if n_images > 1:
            for (k, tl) in enumerate(tab_titles):
                wid.children[1].set_title(k, tl)
        else:
            for (k, tl) in enumerate(tab_titles):
                wid.set_title(k, tl)

    # align-start the image number widget and the rest
    if n_images > 1:
        wid.add_class('align-start')

    # format options' widgets
    if n_images > 1:
        format_animation_options(image_number_wid, index_text_width='0.5cm',
                                 container_padding='6px',
                                 container_margin='6px',
                                 container_border='1px solid black',
                                 toggle_button_font_weight='bold',
                                 border_visible=False)
    format_channel_options(channel_options_wid, container_padding='6px',
                           container_margin='6px',
                           container_border='1px solid black',
                           toggle_button_font_weight='bold',
                           border_visible=False)
    format_landmark_options(landmark_options_wid, container_padding='6px',
                            container_margin='6px',
                            container_border='1px solid black',
                            toggle_button_font_weight='bold',
                            border_visible=False)
    format_figure_options(figure_options_wid, container_padding='6px',
                          container_margin='6px',
                          container_border='1px solid black',
                          toggle_button_font_weight='bold',
                          border_visible=False)
    format_info_print(info_wid, font_size_in_pt='9pt', container_padding='6px',
                      container_margin='6px',
                      container_border='1px solid black',
                      toggle_button_font_weight='bold', border_visible=False)
    format_save_figure_options(save_figure_wid, container_padding='6px',
                               container_margin='6px',
                               container_border='1px solid black',
                               toggle_button_font_weight='bold',
                               tab_top_margin='0cm', border_visible=False)

    # update widgets' state for image number 0
    update_widgets('', 0)

    # Reset value to trigger initial visualization
    landmark_options_wid.children[1].children[1].value = False
Exemple #5
0
def visualize_shapes(shapes, figure_size=(7, 7), popup=False, **kwargs):
    r"""
    Widget that allows browsing through a list of shapes.

    Parameters
    -----------
    shapes : `list` of :map:`LandmarkManager` or subclass
        The list of shapes to be displayed. Note that the shapes can have
        different attributes between them, i.e. different landmark groups and
        labels etc.

    figure_size : (`int`, `int`), optional
        The initial size of the plotted figures.

    popup : `boolean`, optional
        If enabled, the widget will appear as a popup window.

    kwargs : `dict`, optional
        Passed through to the viewer.
    """
    import matplotlib.pyplot as plt

    # make sure that shapes is a list even with one shape member
    if not isinstance(shapes, list):
        shapes = [shapes]

    # find number of shapes
    n_shapes = len(shapes)

    # find initial groups and labels that will be passed to the landmark options
    # widget creation
    first_has_landmarks = shapes[0].n_groups != 0
    if first_has_landmarks:
        initial_groups_keys, initial_labels_keys = \
            _exrtact_group_labels_landmarks(shapes[0])
    else:
        initial_groups_keys = [' ']
        initial_labels_keys = [[' ']]

    # Define plot function
    def plot_function(name, value):
        # clear current figure, but wait until the new data to be displayed are
        # generated
        clear_output(wait=True)

        # get params
        s = 0
        if n_shapes > 1:
            s = image_number_wid.selected_index
        axis_mode = axes_mode_wid.value
        x_scale = figure_options_wid.x_scale
        y_scale = figure_options_wid.y_scale
        axes_visible = figure_options_wid.axes_visible

        # get the current figure id
        figure_id = plt.figure(save_figure_wid.figure_id.number)

        # plot
        if (landmark_options_wid.landmarks_enabled and
                    landmark_options_wid.group != ' '):
            # invert axis if image mode is enabled
            if axis_mode == 1:
                plt.gca().invert_yaxis()

            # plot
            shapes[s].view(
                group=landmark_options_wid.group,
                with_labels=landmark_options_wid.with_labels,
                image_view=axis_mode == 1,
                render_legend=landmark_options_wid.legend_enabled,
                render_numbering=landmark_options_wid.numbering_enabled,
                **kwargs)
            plt.hold(False)
            plt.gca().axis('equal')
            # set figure size
            plt.gcf().set_size_inches([x_scale, y_scale] *
                                      np.asarray(figure_size))
            # turn axis on/off
            if not axes_visible:
                plt.axis('off')
            plt.show()

        # save the current figure id
        save_figure_wid.figure_id = figure_id

        # info_wid string
        if landmark_options_wid.group != ' ':
            info_txt = r"""
                {} landmark points.
                Shape range: {:.1f} x {:.1f}.
                Shape centre: {:.1f} x {:.1f}.
                Shape norm is {:.2f}.
            """.format(shapes[s][landmark_options_wid.group][None].n_points,
                       shapes[s][landmark_options_wid.group][None].range()[0],
                       shapes[s][landmark_options_wid.group][None].range()[1],
                       shapes[s][landmark_options_wid.group][None].centre()[0],
                       shapes[s][landmark_options_wid.group][None].centre()[1],
                       shapes[s][landmark_options_wid.group][None].norm())
        else:
            info_txt = "There are no landmarks."

        info_wid.children[1].value = _raw_info_string_to_latex(info_txt)

    # create options widgets
    # The landmarks checkbox default value if the first image doesn't have
    # landmarks
    landmark_options_wid = landmark_options(
        initial_groups_keys, initial_labels_keys, plot_function,
        toggle_show_default=True, landmarks_default=first_has_landmarks,
        legend_default=True, numbering_default=False, toggle_show_visible=False)
    # if only a single image is passed in and it doesn't have landmarks, then
    # landmarks checkbox should be disabled
    landmark_options_wid.children[1].children[0].disabled = \
        not first_has_landmarks
    figure_options_wid = figure_options(plot_function, scale_default=1.,
                                        show_axes_default=False,
                                        toggle_show_default=True,
                                        toggle_show_visible=False)
    axes_mode_wid = RadioButtonsWidget(values={'Image': 1, 'Point cloud': 2},
                                       description='Axes mode:', value=1)
    axes_mode_wid.on_trait_change(plot_function, 'value')
    ch = list(figure_options_wid.children)
    ch.insert(3, axes_mode_wid)
    figure_options_wid.children = ch
    info_wid = info_print(toggle_show_default=True, toggle_show_visible=False)
    initial_figure_id = plt.figure()
    save_figure_wid = save_figure_options(initial_figure_id,
                                          toggle_show_default=True,
                                          toggle_show_visible=False)

    # define function that updates options' widgets state
    def update_widgets(name, value):
        # get new groups and labels, update landmark options and format them
        group_keys, labels_keys = _exrtact_group_labels_landmarks(shapes[value])
        update_landmark_options(landmark_options_wid, group_keys,
                                labels_keys, plot_function)
        format_landmark_options(landmark_options_wid, container_padding='6px',
                                container_margin='6px',
                                container_border='1px solid black',
                                toggle_button_font_weight='bold',
                                border_visible=False)

    # create final widget
    if n_shapes > 1:
        # image selection slider
        image_number_wid = animation_options(
            index_min_val=0, index_max_val=n_shapes-1,
            plot_function=plot_function, update_function=update_widgets,
            index_step=1, index_default=0,
            index_description='Shape Number', index_minus_description='<',
            index_plus_description='>', index_style='buttons',
            index_text_editable=True, loop_default=True, interval_default=0.3,
            toggle_show_title='Shape Options', toggle_show_default=True,
            toggle_show_visible=False)

        # final widget
        cont_wid = TabWidget(children=[info_wid, landmark_options_wid,
                                       figure_options_wid, save_figure_wid])
        wid = ContainerWidget(children=[image_number_wid, cont_wid])
        button_title = 'Shapes Menu'
    else:
        # final widget
        wid = TabWidget(children=[info_wid, landmark_options_wid,
                                  figure_options_wid, save_figure_wid])
        button_title = 'Shape Menu'
    # create popup widget if asked
    if popup:
        wid = PopupWidget(children=[wid], button_text=button_title)

    # display final widget
    display(wid)

    # set final tab titles
    tab_titles = ['Shape info', 'Landmarks options', 'Figure options',
                  'Save figure']
    if popup:
        if n_shapes > 1:
            for (k, tl) in enumerate(tab_titles):
                wid.children[0].children[1].set_title(k, tl)
        else:
            for (k, tl) in enumerate(tab_titles):
                wid.children[0].set_title(k, tl)
    else:
        if n_shapes > 1:
            for (k, tl) in enumerate(tab_titles):
                wid.children[1].set_title(k, tl)
        else:
            for (k, tl) in enumerate(tab_titles):
                wid.set_title(k, tl)

    # align-start the image number widget and the rest
    if n_shapes > 1:
        wid.add_class('align-start')

    # format options' widgets
    if n_shapes > 1:
        format_animation_options(image_number_wid, index_text_width='0.5cm',
                                 container_padding='6px',
                                 container_margin='6px',
                                 container_border='1px solid black',
                                 toggle_button_font_weight='bold',
                                 border_visible=False)
    format_landmark_options(landmark_options_wid, container_padding='6px',
                            container_margin='6px',
                            container_border='1px solid black',
                            toggle_button_font_weight='bold',
                            border_visible=False)
    format_figure_options(figure_options_wid, container_padding='6px',
                          container_margin='6px',
                          container_border='1px solid black',
                          toggle_button_font_weight='bold',
                          border_visible=False)
    format_info_print(info_wid, font_size_in_pt='9pt', container_padding='6px',
                      container_margin='6px',
                      container_border='1px solid black',
                      toggle_button_font_weight='bold', border_visible=False)
    format_save_figure_options(save_figure_wid, container_padding='6px',
                               container_margin='6px',
                               container_border='1px solid black',
                               toggle_button_font_weight='bold',
                               tab_top_margin='0cm', border_visible=False)

    # update widgets' state for image number 0
    update_widgets('', 0)

    # Reset value to trigger initial visualization
    landmark_options_wid.children[1].children[1].value = False
class InteractiveInput(object):
    
    def __init__(self, name='', version='', equations=None, parameters=None,
                 get_parameters=None, auxiliary_variables=[], constraints=[],
                 symbols={}, resolve_cycles=False, resolve_codominance=False,
                 centered_axes=False, xaxis=None, yaxis=None, recast=True,
                 x_range=[1e-3, 1e3], y_range=[1e-3, 1e3],
                 zlim=None, by_signature=False, kinetic_orders=None,
                 included_cases=None, biological_constraints=[], resolution=100,
                 **kwargs):
        ''' 
        '''
        setattr(self, 'ds', None)
        setattr(self, 'equations', [])
        setattr(self, 'name', name)
        setattr(self, 'version', version)
        setattr(self, 'pvals', None)
        setattr(self, 'cyclical', resolve_cycles)
        setattr(self, 'codominance', resolve_codominance)
        setattr(self, 'recast', recast)
        setattr(self, 'auxiliary', [])
        setattr(self, 'constraints', [])
        setattr(self, 'kinetic_orders', [])
        setattr(self, 'symbols', symbols)
        setattr(self, 'widget', Tab())
        setattr(self, 'figures', None)
        setattr(self, 'figure_data', [])
        setattr(self, 'tables', None)
        setattr(self, 'table_data', [])
        setattr(self, 'display_system', None)
        setattr(self, 'options', dict(kwargs))
        self.options.update(center_axes=centered_axes, 
                            xaxis=xaxis, yaxis=yaxis,
                            range_x=x_range, range_y=y_range, zlim=zlim, 
                            by_signature=by_signature, 
                            kinetic_orders=kinetic_orders, 
                            get_parameters=get_parameters,
                            included_cases=included_cases,
                            biological_constraints=biological_constraints,
                            resolution=resolution)
        if equations is not None:
            self.equations = equations
            if isinstance(equations, list) is False:
                self.equations = [equations]
        
        if auxiliary_variables is not None:
            self.auxiliary = auxiliary_variables
            if isinstance(auxiliary_variables, list) is False:
                self.auxiliary = [auxiliary_variables]
                
        if constraints is not None:
            self.constraints = constraints
            if isinstance(constraints, list) is False:
                self.constraints = [constraints]
                
        if parameters is not None:
            self.pvals = dspace.VariablePool(names = parameters.keys())
            self.pvals.update(parameters)
        self.root = VBox(children=[self.widget])
        display(self.root)   
        self.update_child('About', self.help_widget())
        self.update_child('Main Menu', self.edit_equations_widget())

        
    def set_defaults(self, key, value):
        self.options[key] = value
        
    def defaults(self, key):
        if key in self.options:
            return self.options[key]
        else:
            return None        
        
    def reload_widgets(self):
        self.widget = Tab()
        display(self.root)
        self.update_child('Main Menu', self.edit_equations_widget())
        if self.ds is None:
            return
        self.update_widgets()
        self.figures.load_widgets()
        
    def child_with_name(self, name):
        children = self.widget.children
        for i in xrange(len(children)):
            if children[i].description == name:
                return self.widget.children[i]
        return None
    
    def update_child(self, name, child, index=None):
        previous_children = self.widget.children
        children = [i for i in self.widget.children]
        added = False
        for i in xrange(len(children)):
            if children[i].description == name:
                self.widget._titles = {}
                old = children.pop(i)
                break
        if added is False:
            if child is not None:
                child.description = name
                children.append(child)
                index = len(children)-1
            else:
                index = 0
        self.widget.children = children
        for (i, child) in enumerate(children):
            self.widget.set_title(i, child.description)
        self.widget.selected_index = index
        
    def enumerate_phenotypes_menu(self, b):
        cases_table = CasesTable(self)
        return cases_table.cases_table_widget()
        
        
    def case_report_menu(self, b):
        case_report = CaseReport(self, 
                                 self.defaults('by_signature'))
        return case_report.create_case_widget()

    def co_localize_menu(self, b):
        case_report = CaseColocalization(self, 
                                         self.defaults('by_signature'))
        return case_report.colocalization_widget()
    
    def case_intersect_menu(self, b):
        case_report = CaseIntersection(self,
                                       self.defaults('by_signature'))
        return case_report.case_intersection_widget()

    
    def create_plot_menu(self, b):
        plot = MakePlot(self)
        return plot.create_plot_widget()
        
    def load_widget(self, b):
        self.name = str(b.name.value)
        self.version = str(self.version_field.value)
        saved = WidgetSavedData.load_widget_data(self)
        b.wi.visible = True
        if self.ds is None:
            return
        self.make_options_menu(b.button)
        self.update_widgets()
        self.figures.load_widgets()       
        self.tables.load_widgets()       
        ## b.version.value = self.version
        self.widget.selected_index = 0
        
    def save_widget_data(self, b):
        save_widget = SavePopupWidget(self)
        widget_container = save_widget.save_popup_widget()
        self.root.children = [self.widget, widget_container]
        self.widget.visible = False
                
    def modify_equations_widget(self, b):
        self.ds = None
        self.figure_data = []
        self.table_data = []
        self.widget.close()
        self.widget = Tab()
        display(self.root)   
        self.update_child('Main Menu', self.edit_equations_widget(editing=True))
        
    def make_options_menu(self, b):
        wi = b.wi
        b.visible = False
        b.name.visible = False
        b.load.visible = False
        actions = [('Enumerate Phenotypes', self.enumerate_phenotypes_menu),
                   ('Analyze Case', self.case_report_menu),
                   ('Intersect Phenotypes', self.case_intersect_menu),
                   ('Co-localize Phenotypes', self.co_localize_menu),
                   ('Create Plot', self.create_plot_menu)]
        actions_h = HTML(value='<b>Actions</b>')
        options_h = HTML(value='<b>Options</b>')
        options = [('Edit Symbols', self.create_edit_symbols),
                   ('Edit Parameters', self.create_edit_parameters),
                   ('Save Data', self.save_widget_data)]
        actions_w = Tab()
        options_w = []
        for name, method in options:
            button = Button(description=name)
            button.on_click(method)
            ## button.version = b.version
            if method is None:
                button.disabled = True
            options_w.append(button)
        edit = Button(description='Modify System')
        edit.on_click(self.modify_equations_widget)
        warning = HTML()
        warning.value = '<font color="red"><b>Warning! Modifying system erases saved figures and tables.</b></font>'
        wi.children = [actions_h, actions_w] + [options_h] + options_w + [edit, warning]
        for title, method in actions:
            title, widget = method(self)
            children = [i for i in actions_w.children] + [widget]
            actions_w.children = children
            actions_w.set_title(len(children)-1, title)
        self.widget.selected_index = 1
        
        
    def update_widgets(self):
        self.display_system = DisplaySystem(self)
        self.display_system.create_system_widget()
        self.figures = DisplayFigures(self)
        self.figures.create_figures_widget()
        self.tables = DisplayTables(self)
        self.tables.create_tables_widget()
                
    def help_widget(self):
        about_str = ['<p style="text-align:justify;"><font color="darkblue">',
                     'You are using the Design Space Toolbox V2 Jupyter',
                     'Notebook-based widget, a graphical interface for',
                     'the Design Space Toolbox V2 created by Jason',
                     'Lomnitz in the laboratory of Michael A. Savageau.',
                     '<br><br>',
                     'This software has been created for the analysis',
                     'of mathematical models of biochemical systems.',
                     'This library deconstructs a model into a series of',
                     'sub-models that can be analyzed by applying a series',
                     'of numerical and symbolic methods.',
                     '<br><br>',
                     'To begin, please enter the information in the required',
                     'fields (marked by an "*") and optional fields.',
                     'The Name field is used to save and load a model',
                     'workspace,which includes the system equations, tables'
                     ' and figures.  The primary input into the widget are the',
                     'system equations, represented by a list of strings.',
                     '<br><br></font>',
                     'The equations must satisfy the following rules:<br>',
                     '1. Each equation has to be explicitly stated as:<br>',
                     '1.1 A differential equation, where the "." operator',
                     'denotes the derivative with respect to time.<br>',
                     '1.2 An algebraic constraint, where the left hand side',
                     'is either a variable or a mathematical expression.',
                     'Auxiliary variables associated with the constraint must',
                     'be explicitly defined (unless the left-hand side is the',
                     'auxiliary variable).',
                     '<br>',
                     '2. Multiplication is represented by the "*" operator.',
                     '<br>',
                     '3. Powers are represented by the "^" operator.',
                     '<br>',
                     '4. Architectural constraints are defined as inequalities,',
                     'where both sides of the inequality are products of',
                     'power-laws.<br><br>',
                     '</p>']
        report_str = ['<p style="text-align:center;">',
                      'This software is a still under active development and may',
                      'contain a number of bugs and issues.  A complete list of',
                      'known open issues can be found online here: ',
                      '<a target="_blank"',
                      'href="https://bitbucket.org/jglomnitz/design-space-toolbox/issues?status=new&status=open">',
                      'Project Issue Tracker</a>.<br>',
                      '<font color="red"><b>If you found a new bug in the stable',
                      'or release version of the design space toolbox; or would',
                      'like to request an enhancement that has not yet',
                      'been reported, please report it here:</b></font>',
                      '<a target="_blank"',
                      'href="https://bitbucket.org/jglomnitz/design-space-toolbox/issues/new?title=Issue%20name">',
                      'REPORT BUG</a>',      
                      '</p>']
                         
        html = HTML(value=' '.join(report_str)+' '.join(about_str))
        return VBox(children=[html])
        
    def edit_equations_widget(self, editing=False):
        kinetic_orders = self.options['kinetic_orders']
        if kinetic_orders is None:
            kinetic_orders = []
        name = Text(description='* Name', value=self.name)
        version = Text(description='Version', value=self.version)
        self.version_field = version
        equations=Textarea(description='* Equations',
                                         value='\n'.join(self.equations))
        aux=Textarea(description='Auxiliary Variables',
                                   value=', '.join(self.auxiliary))
        html = HTML(value='<b>Architectural Constraints</b>')
        constraints=Textarea(description='Parameters',
                             value=', '.join(self.constraints)
                             )
        options_html = HTML(value='<b>Additional Options</b>')
        cyclical = Checkbox(description='Check for Cycles',
                            value = self.cyclical)
        codominance = Checkbox(description='Check for Co-dominance',
                               value = self.codominance)
        recast = Checkbox(description='Recast Equations',
                               value = self.recast)
        replacements=Textarea(description='Kinetic Orders',
                              value=', '.join(
                               [i for i in kinetic_orders]))
        wi = VBox(children=[equations, 
                            aux, html,
                            constraints, replacements,
                            options_html, cyclical,
                            codominance,recast,
                            ])
        button = Button(value=False, 
                                      description='Create Design Space')
        button.on_click(self.make_design_space)
        button.equations = equations
        button.aux = aux
        button.constraints = constraints
        button.cyclical = cyclical
        button.codominance = codominance
        button.recast = recast
        button.replacements = replacements
        button.wi = wi
        button.name = name
        ## button.version = version
        load = Button(value=False, 
                      description='Load Data')
        load.on_click(self.load_widget)
        load.equations = equations
        ## load.version = version
        load.aux = aux
        load.constraints = constraints
        load.cyclical = cyclical
        load.codominance = codominance
        load.replacements = replacements
        load.wi = wi
        load.name = name
        load.button = button
        button.load = load
        edit_symbols = Button(value=False, description='Edit Symbols')
        edit_symbols.on_click(self.create_edit_symbols)
        edit_parameters = Button(value=False, description='Edit Parameters')
        edit_parameters.on_click(self.create_edit_parameters)
        button.edit_symbols = edit_symbols
        button.edit_parameters = edit_parameters
        edit_equations = VBox(description='Edit Equations', 
                              children=[name, version, wi, 
                                        edit_symbols,
                                        edit_parameters,
                                        button,
                                        load])
        wi.visible = False
        edit_symbols.visible = False
        edit_parameters.visible = False
        if self.ds is not None:
            wi.visible = True
            ## self.update_widgets()
            self.make_options_menu(button)
        if editing is True:
            self.make_design_space(button)
        return edit_equations  
        
    def make_design_space(self, b):
        if b.wi.visible == False:
            b.wi.visible = True
            b.description = 'Done'
            return
        self.version_field.visible = False
        self.equations = [i.strip() for i in str(b.equations.value).split('\n') if len(i.strip()) > 0]
        self.auxiliary = [i.strip() for i in str(b.aux.value).split(',') if len(i.strip()) > 0] 
        self.constraints = [i.strip() for i in str(b.constraints.value).split(',') if len(i.strip()) > 0] 
        self.cyclical = b.cyclical.value
        self.codominance = b.codominance.value
        self.recast = b.recast.value
        eq = dspace.Equations(self.equations,
                              auxiliary_variables=self.auxiliary, 
                              latex_symbols=self.symbols)
        if self.recast:
            eq = eq.recast()
        self.name = b.name.value
        constraints = self.constraints
        replacements = str(b.replacements.value).strip()
        self.options.update(kinetic_orders=str(b.replacements.value).split(','))
        if len(replacements) > 0:
            replacements = str(b.replacements.value).split(',')
            replacements = [[j.strip() for j in i.split('=')] for i in replacements] 
            parameter_dict = {i:j for i,j in replacements}
        else:
            parameter_dict = {}
        if len(constraints) == 0:
            constraints = None
        self.ds = dspace.DesignSpace(eq, name=b.name.value, 
                                     constraints=constraints,
                                     resolve_cycles=self.cyclical, 
                                     resolve_codominance=self.codominance,
                                     parameter_dict=parameter_dict)
        if self.pvals == None:
            self.pvals = dspace.VariablePool(
                          names=self.ds.independent_variables
                          )
        else:
            pvals = dspace.VariablePool(
                     names=self.ds.independent_variables
                     )
            for i in pvals:
                if i in self.pvals:
                    pvals[i] = self.pvals[i]
            self.pvals = pvals
        get_parameters = self.defaults('get_parameters')
        if get_parameters is not None:
             case = self.ds(get_parameters)
             self.pvals = case.valid_interior_parameter_set()
        self.symbols.update({i:i for i in self.ds.dependent_variables + self.ds.independent_variables if i not in self.symbols})
        self.ds.update_latex_symbols(self.symbols)
        self.update_widgets()
        self.make_options_menu(b)
    
    def create_edit_symbols(self, b):
        Edit = EditSymbols(self)
        Edit.edit_symbols_widget() 
               
    def create_edit_parameters(self, b):
        Edit = EditParameters(self)
        Edit.edit_parameters_widget()