コード例 #1
0
class ArrowDesigner(WindowedPlugin):
    """
    The ArrowDesigner plugin that subclasses WindowedPlugin.
    """
    metadata = PluginMetadata(
        name='ArrowDesigner',
        author='Gary Geng',
        version='0.0.1',
        short_desc='Arrow tip designer for reactions.',
        long_desc='Arrow tip designer for reactions.',
        category=PluginCategory.APPEARANCE,
    )

    def __init__(self):
        super().__init__()
        self.arrow_tip = api.get_arrow_tip()

    def create_window(self, dialog):
        """
        Called when creating a window. Create the designer window as well as control buttons.
        """
        window = wx.Window(dialog, size=(500, 500))
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.designer = DesignerWindow(window, self.arrow_tip)
        save_btn = wx.Button(window, label='Save')
        save_btn.Bind(wx.EVT_BUTTON, self.OnSave)
        restore_btn = wx.Button(window, label='Restore default')
        restore_btn.Bind(wx.EVT_BUTTON, self.OnRestore)
        sizerflags = wx.SizerFlags().Align(wx.ALIGN_CENTER_HORIZONTAL).Border(
            wx.TOP, 20)
        sizer.Add(self.designer, sizerflags)
        sizer.Add(save_btn, sizerflags)
        sizer.Add(restore_btn, sizerflags)
        dialog.SetSizer(sizer)
        return window

    def OnSave(self, evt):
        """
        Handler for the "save" button. Save the new arrow tip.
        """
        api.set_arrow_tip(self.arrow_tip)

    def OnRestore(self, evt):
        """
        Update the arrow point to be set to default values.
        """
        default_tip = api.get_default_arrow_tip()
        api.set_arrow_tip(default_tip)
        self.designer.update_arrow_tip(default_tip)
コード例 #2
0
class ExportAntimony(WindowedPlugin):
    metadata = PluginMetadata(
        name='ExportAntimony',
        author='Jin Xu',
        version='0.0.2',
        short_desc='Export Antimony.',
        long_desc='Export the Antimony String from the network on canvas.',
        category=PluginCategory.ANALYSIS)

    def create_window(self, dialog):
        """
        Create a window to do the antimony export.
        Args:
            self
            dialog
        """
        self.window = wx.Panel(dialog, pos=(5, 100), size=(300, 320))

        export_btn = wx.Button(self.window, -1, 'Export', (5, 5))
        export_btn.Bind(wx.EVT_BUTTON, self.Export)

        save_btn = wx.Button(self.window, -1, 'Save', (100, 5))
        save_btn.Bind(wx.EVT_BUTTON, self.Save)

        wx.StaticText(self.window, -1, 'Antimony string:', (5, 30))
        self.antimonyText = wx.TextCtrl(self.window,
                                        -1,
                                        "", (10, 50),
                                        size=(260, 220),
                                        style=wx.TE_MULTILINE)
        self.antimonyText.SetInsertionPoint(0)

        return self.window

    def Export(self, evt):
        """
        Handler for the "Export" button.
        Get the network on canvas and change it to an Antimony string.
        """
        isReversible = True
        netIn = 0
        numNodes = api.node_count(netIn)

        if numNodes == 0:
            wx.MessageBox("Please import a network on canvas", "Message",
                          wx.OK | wx.ICON_INFORMATION)
        else:
            allNodes = api.get_nodes(netIn)
            id = allNodes[0].id[0:-2]
            numReactions = api.reaction_count(netIn)
            antStr = ''
            allReactions = api.get_reactions(netIn)
            for i in range(numReactions):
                antStr = antStr + 'J' + str(i) + ': '
                rct_num = len(allReactions[i].sources)
                prd_num = len(allReactions[i].targets)
                for j in range(rct_num - 1):
                    antStr = antStr + id + '_' + str(
                        allReactions[i].sources[j])
                    antStr = antStr + ' + '
                antStr = antStr + id + '_' + str(
                    allReactions[i].sources[rct_num - 1])
                antStr = antStr + ' -> '
                for j in range(prd_num - 1):
                    antStr = antStr + id + '_' + str(
                        allReactions[i].targets[j])
                    antStr = antStr + ' + '
                antStr = antStr + id + '_' + str(
                    allReactions[i].targets[prd_num - 1])
                antStr = antStr + '; E' + str(i) + '*(k' + str(i)
                for j in range(rct_num):
                    antStr = antStr + '*' + id + '_' + str(
                        allReactions[i].sources[j])
                if isReversible:
                    antStr = antStr + ' - k' + str(i) + 'r'
                    for j in range(prd_num):
                        antStr = antStr + '*' + id + '_' + str(
                            allReactions[i].targets[j])
                antStr = antStr + ')'
                antStr = antStr + ';\n'
            self.antimonyText.SetValue(antStr)

    def Save(self, evt):
        """
        Handler for the "Save" button.
        Save the Antimony string to a file.
        """

        self.dirname = ""  #set directory name to blank

        dlg = wx.FileDialog(self.window,
                            "Save As",
                            self.dirname,
                            wildcard="Antimony files (*.ant)|*.ant",
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            # Grab the content to be saved
            itcontains = self.antimonyText.GetValue()
            # Open the file for write, write, close
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            filehandle = open(os.path.join(self.dirname, self.filename), 'w')
            filehandle.write(itcontains)
            filehandle.close()
        # Get rid of the dialog to keep things tidy
        dlg.Destroy()
コード例 #3
0
class IMPORTSBML(WindowedPlugin):
    metadata = PluginMetadata(
        name='ImportSBML',
        author='Jin Xu',
        version='0.0.2',
        short_desc='Import SBML.',
        long_desc='Import an SBML String from a file and visualize it as a network on canvas.',
        category=PluginCategory.ANALYSIS
    )


    def create_window(self, dialog):
        """
        Create a window to import SBML.
        Args:
            self
            dialog
        """
        self.window = wx.Panel(dialog, pos=(5,100), size=(300, 320))
        self.sbmlStr = ''
        import_btn = wx.Button(self.window, -1, 'Import', (5, 5))
        import_btn.Bind(wx.EVT_BUTTON, self.Import)

        visualize_btn = wx.Button(self.window, -1, 'Visualize', (100, 5))
        visualize_btn.Bind(wx.EVT_BUTTON, self.Visualize)

        wx.StaticText(self.window, -1, 'SBML string:', (5,30))
        self.SBMLText = wx.TextCtrl(self.window, -1, "", (10, 50), size=(260, 220), style=wx.TE_MULTILINE)
        self.SBMLText.SetInsertionPoint(0)

        return self.window

    def Import(self, evt):
        """
        Handler for the "Import" button.
        Open the SBML file and show it in the TextCtrl box.
        """
        self.dirname=""  #set directory name to blank
        dlg = wx.FileDialog(self.window, "Choose a file to open", self.dirname, wildcard="SBML files (*.xml)|*.xml", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) #open the dialog boxto open file
        if dlg.ShowModal() == wx.ID_OK:  #if positive button selected....
            self.filename = dlg.GetFilename()  #get the filename of the file
            self.dirname = dlg.GetDirectory()  #get the directory of where file is located
            f = open(os.path.join(self.dirname, self.filename), 'r')  #traverse the file directory and find filename in the OS
            self.sbmlStr = f.read()
            self.SBMLText.SetValue(f.read())  #open the file from location as read
            self.SBMLText.WriteText(self.sbmlStr)
            f.close
        dlg.Destroy()

    def Visualize(self, evt):
        """
        Handler for the "Visualize" button.
        Visualize the SBML string to a network shown on the canvas.
        """

        def hex_to_rgb(value):
            value = value.lstrip('#')
            return tuple(int(value[i:i+2], 16) for i in (0, 2, 4))      

        if len(self.sbmlStr) == 0:
            wx.MessageBox("Please import an SBML file.", "Message", wx.OK | wx.ICON_INFORMATION)

        else:
            net_index = 0
            api.clear_network(net_index)
            comp_id_list = []
            comp_dimension_list = []
            comp_position_list = []
            spec_id_list =[]
            spec_dimension_list =[]
            spec_position_list = []


            #set the default values without render info:
            comp_fill_color = (158, 169, 255)
            comp_border_color = (0, 29, 255)
            comp_border_width = 2.0
            spec_fill_color = (255, 204, 153)
            spec_border_color = (255, 108, 9)
            spec_border_width = 2.0
            reaction_line_color = (129, 123, 255)
            reaction_line_width = 3.0

            ### from here for layout ###
            document = readSBMLFromString(self.sbmlStr)
            model_layout = document.getModel()
            mplugin = (model_layout.getPlugin("layout"))

            if mplugin is None:
                wx.MessageBox("There is no layout information, so positions are randomly assigned.", "Message", wx.OK | wx.ICON_INFORMATION)

            #
            # Get the first Layout object via LayoutModelPlugin object.
            #
            else:
                layout = mplugin.getLayout(0)
                if layout is None:
                    wx.MessageBox("There is no layout information, so positions are randomly assigned.", "Message", wx.OK | wx.ICON_INFORMATION)
                else:
                    numCompGlyphs = layout.getNumCompartmentGlyphs()
                    numSpecGlyphs = layout.getNumSpeciesGlyphs()

                    for i in range(numCompGlyphs):
                        compGlyph = layout.getCompartmentGlyph(i)
                        temp_id = compGlyph.getCompartmentId()
                        comp_id_list.append(temp_id)	
                        boundingbox = compGlyph.getBoundingBox()
                        height = boundingbox.getHeight()
                        width = boundingbox.getWidth()
                        pos_x = boundingbox.getX()
                        pos_y = boundingbox.getY()
                        comp_dimension_list.append([width,height])
                        comp_position_list.append([pos_x,pos_y])

                    for i in range(numSpecGlyphs):
                        specGlyph = layout.getSpeciesGlyph(i)
                        spec_id = specGlyph.getSpeciesId()
                        spec_id_list.append(spec_id)
                        boundingbox = specGlyph.getBoundingBox()
                        height = boundingbox.getHeight()
                        width = boundingbox.getWidth()
                        pos_x = boundingbox.getX()
                        pos_y = boundingbox.getY()
                        spec_dimension_list.append([width,height])
                        spec_position_list.append([pos_x,pos_y])

                    rPlugin = layout.getPlugin("render")
                    if (rPlugin != None and rPlugin.getNumLocalRenderInformationObjects() > 0):
                        info = rPlugin.getRenderInformation(0)
                        color_list = []
                        for  j in range ( 0, info.getNumColorDefinitions()):
                            color = info.getColorDefinition(j)			  
                            color_list.append([color.getId(),color.createValueString()])
                        for j in range (0, info.getNumStyles()):
                            style = info.getStyle(j)
                            group = style.getGroup()
                            typeList = style.createTypeString()
                            if 'COMPARTMENTGLYPH' in typeList:
                                for k in range(len(color_list)):
                                    if color_list[k][0] == group.getFill():
                                        comp_fill_color = hex_to_rgb(color_list[k][1])
                                    if color_list[k][0] == group.getStroke():
                                        comp_border_color = hex_to_rgb(color_list[k][1])
                                comp_border_width = group.getStrokeWidth()
                            elif 'SPECIESGLYPH' in typeList:
                                for k in range(len(color_list)):
                                    if color_list[k][0] == group.getFill():
                                        spec_fill_color = hex_to_rgb(color_list[k][1])
                                    if color_list[k][0] == group.getStroke():
                                        spec_border_color = hex_to_rgb(color_list[k][1])
                                spec_border_width = group.getStrokeWidth()
                            elif 'REACTIONGLYPH' in typeList:
                                for k in range(len(color_list)):
                                    if color_list[k][0] == group.getStroke():
                                        reaction_line_color = hex_to_rgb(color_list[k][1])
                                reaction_line_width = group.getStrokeWidth()


            model = simplesbml.loadSBMLStr(self.sbmlStr)
            
            numFloatingNodes  = model.getNumFloatingSpecies()
            FloatingNodes_ids = model.getListOfFloatingSpecies()
            numBoundaryNodes  = model.getNumBoundarySpecies()
            BoundaryNodes_ids = model.getListOfBoundarySpecies() 
            numRxns   = model.getNumReactions()
            Rxns_ids  = model.getListOfReactionIds()
            numComps  = model.getNumCompartments()
            Comps_ids = model.getListOfCompartmentIds()
            numNodes = numFloatingNodes + numBoundaryNodes

            for i in range(numComps):
                temp_id = Comps_ids[i]
                vol= model.getCompartmentVolume(i)
                if len(comp_id_list) != 0:
                #if mplugin is not None:
                    for j in range(numComps):
                        if comp_id_list[j] == temp_id:
                            dimension = comp_dimension_list[j]
                            position = comp_position_list[j]
                else:# no layout info about compartment,
                     # then the whole size of the canvas is the compartment size
                    dimension = [4000,2500]
                    position = [0,0] 

                api.add_compartment(net_index, id=temp_id, volume = vol,
                size=Vec2(dimension[0],dimension[1]),position=Vec2(position[0],position[1]),
                fill_color = api.Color(comp_fill_color[0],comp_fill_color[1],comp_fill_color[2]),
                border_color = api.Color(comp_border_color[0],comp_border_color[1],comp_border_color[2]),
                border_width = comp_border_width)


            comp_node_list = [0]*numComps

            for i in range(numComps):
                comp_node_list[i] = []

            if len(comp_id_list) != 0:
            #if mplugin is not None:
                for i in range (numFloatingNodes):
                    temp_id = FloatingNodes_ids[i]
                    comp_id = model.getCompartmentIdSpeciesIsIn(temp_id)
                    for j in range(numNodes):
                        if temp_id == spec_id_list[j]:
                            dimension = spec_dimension_list[j]
                            position = spec_position_list[j] 
                    nodeIdx_temp = api.add_node(net_index, id=temp_id, floatingNode = True, 
                    size=Vec2(dimension[0],dimension[1]), position=Vec2(position[0],position[1]), 
                    fill_color=api.Color(spec_fill_color[0],spec_fill_color[1],spec_fill_color[2]),
                    border_color=api.Color(spec_border_color[0],spec_border_color[1],spec_border_color[2]),
                    border_width=spec_border_width)
                    for j in range(numComps):
                        if comp_id == comp_id_list[j]:
                            comp_node_list[j].append(nodeIdx_temp)

                for i in range (numBoundaryNodes):
                    temp_id = BoundaryNodes_ids[i]
                    comp_id = model.getCompartmentIdSpeciesIsIn(temp_id)
                    for j in range(numNodes):
                        if temp_id == spec_id_list[j]:
                            dimension = spec_dimension_list[j]
                            position = spec_position_list[j] 
                    nodeIdx_temp = api.add_node(net_index, id=temp_id, floatingNode = False, 
                    size=Vec2(dimension[0],dimension[1]), position=Vec2(position[0],position[1]), 
                    fill_color=api.Color(spec_fill_color[0],spec_fill_color[1],spec_fill_color[2]),
                    border_color=api.Color(spec_border_color[0],spec_border_color[1],spec_border_color[2]),
                    border_width=spec_border_width)
                    for j in range(numComps):
                        if comp_id == comp_id_list[j]:
                            comp_node_list[j].append(nodeIdx_temp)

            else: # there is no layout information, assign position randomly and size as default
                comp_id_list = Comps_ids

                for i in range (numFloatingNodes):
                    temp_id = FloatingNodes_ids[i]
                    comp_id = model.getCompartmentIdSpeciesIsIn(temp_id)
                    nodeIdx_temp = api.add_node(net_index, id=temp_id, size=Vec2(60,40), floatingNode = True, 
                    position=Vec2(40 + math.trunc (_random.random()*800), 40 + math.trunc (_random.random()*800)),
                    fill_color=api.Color(spec_fill_color[0],spec_fill_color[1],spec_fill_color[2]),
                    border_color=api.Color(spec_border_color[0],spec_border_color[1],spec_border_color[2]),
                    border_width=spec_border_width)
                    for j in range(numComps):
                        if comp_id == comp_id_list[j]:
                            comp_node_list[j].append(nodeIdx_temp)

                for i in range (numBoundaryNodes):
                    temp_id = BoundaryNodes_ids[i]
                    comp_id = model.getCompartmentIdSpeciesIsIn(temp_id)
                    nodeIdx_temp = api.add_node(net_index, id=temp_id, size=Vec2(60,40), floatingNode = False, 
                    position=Vec2(40 + math.trunc (_random.random()*800), 40 + math.trunc (_random.random()*800)),
                    fill_color=api.Color(spec_fill_color[0],spec_fill_color[1],spec_fill_color[2]),
                    border_color=api.Color(spec_border_color[0],spec_border_color[1],spec_border_color[2]),
                    border_width=spec_border_width)
                    for j in range(numComps):
                        if comp_id == comp_id_list[j]:
                            comp_node_list[j].append(nodeIdx_temp)


            for i in range(numComps):
                temp_id = Comps_ids[i]
                for j in range(numComps):
                    if comp_id_list[j] == temp_id:
                        node_list_temp = comp_node_list[j]
                for j in range(len(node_list_temp)):
                    api.set_compartment_of_node(net_index=net_index, node_index=node_list_temp[j], comp_index=i)

            #handle_positions, center_pos was set as the default

            numNodes = api.node_count(net_index)
            allNodes = api.get_nodes(net_index)

            for i in range (numRxns):
                src = []
                dst = []
                temp_id = Rxns_ids[i]
                kinetics = model.getRateLaw(i)
                rct_num = model.getNumReactants(i)
                prd_num = model.getNumProducts(i)


                for j in range(rct_num):
                    rct_id = model.getReactant(temp_id,j)
                    for k in range(numNodes):
                        if allNodes[k].id == rct_id:
                            src.append(allNodes[k].index)


                for j in range(prd_num):
                    prd_id = model.getProduct(temp_id,j)
                    for k in range(numNodes):
                        if allNodes[k].id == prd_id:
                            dst.append(allNodes[k].index)

                api.add_reaction(net_index, id=temp_id, reactants=src, products=dst, rate_law = kinetics,
                fill_color=api.Color(reaction_line_color[0],reaction_line_color[1],reaction_line_color[2]), 
                line_thickness=reaction_line_width)
            

                
コード例 #4
0
Version 0.01: Author: Gary Geng (2020)
"""

# pylint: disable=maybe-no-member
from rkviewer.utils import opacity_mul
from rkviewer.canvas.state import ArrowTip
import wx
from typing import List, Tuple
from rkplugin import api
from rkplugin.plugins import PluginMetadata, WindowedPlugin
from rkplugin.api import Vec2

metadata = PluginMetadata(name='ArrowDesigner',
                          author='Gary Geng',
                          version='0.0.1',
                          short_desc='Arrow tip designer for reactions.',
                          long_desc='Arrow tip designer for reactions.')


class DesignerWindow(wx.Window):
    """
    Defining the designer window.

    """
    def __init__(self, parent, arrow_tip: ArrowTip):
        """
        Creates the designer window for the arraw to design.

        Args: 
            self: the Designer Window to initialize.
コード例 #5
0
ファイル: align_circle.py プロジェクト: nnguyen19/PyRKViewer
class AlignCircle(WindowedPlugin):
    metadata = PluginMetadata(name='AlignCircle',
                              author='Evan Yip (2021)',
                              version='0.0.1',
                              short_desc='Align Circle',
                              long_desc='Aligns the nodes into a circle',
                              category=PluginCategory.UTILITIES)

    def __init__(self):
        """
        Initialize the AlignCircle

        Args:
            self
        """
        # allows the align circle class to inherit
        # the methods of the Windowed Plugin Class
        super().__init__()

    def create_window(self, dialog):
        """
        Create a window to do the structural analysis.
        Args:
            self
            dialog
        """
        # Making the window
        window = wx.Panel(dialog, pos=(5, 100), size=(300, 155))
        wx.StaticText(window, -1, 'Select nodes to arrange in circle',
                      (15, 10))

        # Use default radius
        wx.StaticText(window, -1, 'Use default radius:', (15, 30))
        self.defaultCheck = wx.CheckBox(window, -1, pos=(150, 30))
        self.defaultCheck.SetValue(True)

        # Making radius setable
        wx.StaticText(window, -1, 'Input desired radius:', (15, 55))
        self.radiusText = wx.TextCtrl(window,
                                      -1,
                                      '0', (150, 55),
                                      size=(120, 22))
        self.radiusText.SetInsertionPoint(0)
        self.radiusText.Bind(wx.EVT_TEXT, self.OnText_radius)  # binding test
        self.radiusValue = float(self.radiusText.GetValue())

        # Making the toggle button
        apply_btn = wx.ToggleButton(window,
                                    -1,
                                    'Apply', (100, 85),
                                    size=(80, 22))
        apply_btn.SetValue(False)
        # Binding the method to the button
        apply_btn.Bind(wx.EVT_TOGGLEBUTTON, self.Apply)
        return window

    def find_center(self, num_nodes, nodes):
        """
        Takes in the number of nodes and list of node indices and
        computes the optimal centerpoint for the circle
        Parameters: num_nodes(int) - number of nodes,
            node_indices(list) - list of nodes indices
        Returns: center(tuple)
        """
        # Max dimension of the node size
        max_dim = 0  # will consider this the diameter of a circle node
        for i in nodes:
            # Get node
            node = api.get_node_by_index(0, i)
            for dim in node.size:
                if dim > max_dim:
                    max_dim = dim

        # Approximate circumference estimate
        spacing = max_dim / 4
        circum_estimate = num_nodes * (max_dim + spacing)

        # Computing radius
        r = circum_estimate / (2 * np.pi) + max_dim

        center = (r, r)
        return center

    def cart(self, r, theta):
        """
        Converts from polar coordinates to cartesian coordinates
        Parameters: r(double), theta(double in radians)
        Returns: (x,y) cartesian coordinate tuple
        """
        x = r * math.cos(theta)
        y = r * math.sin(theta)
        return x, y

    def get_new_position(self, node_index, r, theta):
        """
        Takes in the node index and outputs the new position for that node
        Parameters: r(double), theta(double in radians)
        Returns: (x,y) cartesian coordinate tuple
        """
        node = api.get_node_by_index(0, node_index)
        size = node.size  # (width, height)
        # accounting for slight offset, converting to cartesian
        nodeCenter = self.cart(r - size[0], theta)
        # accounting for node position being specified by top left corner
        x = r + nodeCenter[0] - size[0] / 2
        y = r + nodeCenter[1] + size[1] / 2
        return Vec2(x, y)

    def OnText_radius(self, event):
        """
        Catches exception if self.radiusText can not be converted
        to a floating point number. Opens a window.
        """
        update = event.GetString()
        if update != '':
            try:
                self.radiusValue = float(self.radiusText.GetValue())
            except:
                wx.MessageBox(
                    "Please enter a floating point number"
                    "for the desired radius", "Message",
                    wx.OK | wx.ICON_INFORMATION)

    def CheckSelection(self, nodes):
        """
        Verifies that there are selected nodes. Raises window if
        no nodes are selected, but apply button is pressed
        """
        if nodes == 0:
            wx.MessageBox("Please select desired nodes to arrange"
                          "in circle", "Message", wx.OK | wx.ICON_INFORMATION)
            return True

    def Apply(self, event):
        """
        If apply button is clicked, the nodes will be arranged in a circle
        using either a default radius or a user input radius.
        """
        def translate_nodes(node_indices, r, phi):
            """
            Takes in list of node indices, desired radius, and phi
            and moves the current node
            to its new position
            """
            # Iterate through the nodes and change their position.
            node_num = 0
            for i in node_ind:
                theta = node_num * phi  # angle position for node
                newPos = self.get_new_position(i, r, theta)
                if newPos[0] < 0 or newPos[1] < 0:
                    wx.MessageBox("Please increase radius size", "Message",
                                  wx.OK | wx.ICON_INFORMATION)
                    return
                api.move_node(0, i, newPos, False)
                node_num += 1  # updating node number

        # Get button and checkbox state
        btn_state = event.GetEventObject().GetValue()
        # chk_state = self.OnDefaultCheck()
        chk_state = self.defaultCheck.GetValue()

        # If the button is pressed, arrange the nodes into a circle
        if btn_state is True:
            # Get number of nodes selected
            node_len = len(api.selected_node_indices())
            # get list of node indices
            node_ind = api.selected_node_indices()

            # If no nodes selected raise error
            select = self.CheckSelection(node_len)
            if select is True:
                return

            # If default radius is checked
            if chk_state is True:
                # Compute the expected center of the circle
                center = self.find_center(node_len, node_ind)
                # Compute the angle step between each node
                phi = 2 * math.pi / node_len
                r = center[0]  # radius
                translate_nodes(node_ind, r, phi)

            else:
                r = self.radiusValue
                center = Vec2(r, r)
                phi = 2 * math.pi / node_len  # angle step between each node
                translate_nodes(node_ind, r, phi)  # translating nodes

            # Making the reactions straight lines
            rxns = api.get_reaction_indices(0)
            for rxn in rxns:
                api.update_reaction(net_index=0,
                                    reaction_index=rxn,
                                    use_bezier=False)
            # Setting button state back to False (unclicked)
            event.GetEventObject().SetValue(False)
コード例 #6
0
class LayoutNetworkX(WindowedPlugin):
    metadata = PluginMetadata(
        name='Auto Layout',
        author='Carmen and Herbert M Sauro',
        version='0.5.2',
        short_desc='Auto Layout using networkX.',
        long_desc='Rearrange a random network into a neat auto layout',
        category=PluginCategory.UTILITIES,
    )

    def create_window(self, dialog):
        '''
        Create a window with several inputs and buttons.
        Args:
            self
            dialog
        '''
        # TODO: k, gravity, useMagnetism, useBoundary, useGrid
        self.window = wx.Panel(dialog, pos=(5,100), size=(350, 220))
        self.sizer = wx.FlexGridSizer(cols=2, vgap=10, hgap=0)
        self.sizer.AddGrowableCol(0, 0.6)
        self.sizer.AddGrowableCol(1, 0.4)

        self.sizer.Add((0, 10))
        self.sizer.Add((0, 10))

        self.MaxIterText = wx.TextCtrl(self.window, -1, "100", size=(100, -1))
        self.MaxIterText.SetInsertionPoint(0)
        self.MaxIterText.Bind(wx.EVT_TEXT, self.OnText_MaxIter)
        self.MaxIterValue = int(self.MaxIterText.GetValue())
        self.AddField('Max Number of Iterations', self.MaxIterText)

        self.kText = wx.TextCtrl(self.window, -1, "70", size=(100, -1))
        self.kText.SetInsertionPoint(0)
        self.kText.Bind(wx.EVT_TEXT, self.OnText_k)
        self.kValue = float(self.kText.GetValue())        

        self.AddField('k (float > 0)', self.kText)

        self.scaleText = wx.TextCtrl(self.window, -1, "550", size=(100, -1))
        self.scaleText.SetInsertionPoint(0)
        self.scaleText.Bind(wx.EVT_TEXT, self.OnText_scale)
        self.scaleValue = float(self.scaleText.GetValue())

        self.AddField('Scale of Layout', self.scaleText)

        self.useCentroid = False
        self.centroidCheckBox = wx.CheckBox(self.window)
        self.centroidCheckBox.Bind(wx.EVT_CHECKBOX, self.OnCheckUseCentroid)

        self.AddField('Also Arrange Centroids', self.centroidCheckBox)

        # add spacer left of button
        self.sizer.Add((0, 0))
        apply_btn = wx.Button(self.window, -1, 'Run', (220, 130))
        apply_btn.Bind(wx.EVT_BUTTON, self.Apply)
        self.sizer.Add(apply_btn)
        self.window.SetPosition (wx.Point(10,10))
        self.window.SetSizer(self.sizer)
        return self.window

    def AddField(self, text, field):
        self.sizer.Add(wx.StaticText(self.window, label=text), wx.SizerFlags().Border(wx.LEFT, 20))
        self.sizer.Add(field)

    def OnText_MaxIter(self, evt):
        try:
          update = evt.GetString()
          if update != '':
              self.MaxIterValue = int(self.MaxIterText.GetValue())
        except ValueError:
           wx.MessageBox('Value must be a number', 'Error', wx.OK | wx.ICON_INFORMATION)

    def OnText_k(self, evt):
        try:
           update = evt.GetString()
           if update != '':
              self.kValue = float(self.kText.GetValue())
        except ValueError:
           wx.MessageBox('Value must be a number', 'Error', wx.OK | wx.ICON_INFORMATION)

    def OnText_scale(self, evt):
        try:
           update = evt.GetString()
           if update != '':
              self.scaleValue = float(self.scaleText.GetValue())
        except ValueError:
           wx.MessageBox('Value must be a number', 'Error', wx.OK | wx.ICON_INFORMATION)

    def OnCheckUseCentroid(self, evt):
        cb = evt.GetEventObject() 
        self.useCentroid = cb.GetValue()
           
    def Apply(self, evt):
        if api.node_count(0) == 0:
            return
        G = nx.Graph()
        nodesInd = np.array(list(api.get_node_indices(0)))
        reactionsInd =  np.array(list(api.get_reaction_indices(0)))
        originalPos = {}
        def generateGraph():
            # add nodes and centroids as "nodes" for networkX
            nodes = np.array(list(api.get_node_indices(0)))
            #reactionsInd =  np.array(list(api.get_reaction_indices(0)))
            cStr = np.empty_like(reactionsInd, dtype=str)
            cStr[:,] = "c"
            centroidId = np.char.add(cStr, reactionsInd.astype(str))
            G.add_nodes_from(centroidId)
            nStr = np.empty_like(nodes, dtype=str)
            nStr[:,] = "n"
            nodesId = np.array(list(np.char.add(nStr, nodesInd.astype(str))))
            G.add_nodes_from(nodesId)
            '''
            for n in nodes:
                centroidsTo = np.array(list(api.get_reactions_as_product(0, n))) # Gets the reactions in which it is a product -> TO 
                cStr = np.empty_like(centroidsTo, dtype=str)
                cStr[:,] = "c"
                centroidsToIn = np.char.add(cStr, centroidsTo.astype(str)) # centroids from which the node is product
                centroidsFrom = np.array(list(api.get_reactions_as_reactant(0, n))) # reactions in which it is a reactanr -> FROM
                cStr = np.empty_like(centroidsFrom, dtype=str)
                cStr[:,] = "c"
                centroidsFromIn = np.char.add(cStr, centroidsFrom.astype(str)) # centroids to which the node is reactant
                nS = np.empty_like(centroidsToIn, dtype = str)
                nS[:,] = "n"
                numS = np.empty_like(centroidsToIn, dtype = int)
                numS[:,] = n
                nodeIndArrayTo = np.char.add(nS, numS.astype(str))
                nS = np.empty_like(centroidsFromIn, dtype = str)
                nS[:,] = "n"
                numS = np.empty_like(centroidsFromIn, dtype = int)
                numS[:,] = n
                nodeIndArrayFrom = np.char.add(nS, numS.astype(str))
                edgesTo = np.array(list(zip(centroidsToIn, nodeIndArrayTo)))
                edgesFrom = np.array(list(zip(nodeIndArrayFrom, centroidsFromIn)))
                G.add_edges_from(edgesTo)
                G.add_edges_from(edgesFrom)
            '''

            # Add edges from reactant to centroid and centroid to product (undirected)
            edges = list()
            for reaction in api.get_reactions(0):
                for s in reaction.sources:
                    edges.append(('n' + str(s), 'c' + str(reaction.index)))
                for t in reaction.targets:
                    edges.append(('c' + str(reaction.index), 'n' + str(t)))
                        
            G.add_edges_from(edges)
            cn = 0
            for rea in api.get_reactions(0):
                cent = api.compute_centroid(0, rea.sources, rea.targets)
                #originalPos[centroidId[cn]] = list([cent.x, cent.y])
                originalPos['c' + str(rea)] = list([random.randint(0,600), random.randint(0,600)])
                cn = cn + 1
            
            for nod in api.get_nodes(0):
                #originalPos[nodesId[cn]] = list([nod.position.x, nod.position.y])
                # random.randint(0,500), nod.position.y+random.randint (0,500)])
                originalPos['n' + str(nod)] = list([random.randint(0,600), random.randint (0,600)])
                cn = cn + 1
        generateGraph()
        #print(nx.to_dict_of_lists(G))
        #nodeIds = list (api.get_node_indices(0))
        with api.group_action():   
            for t in range(1):
                pos = (nx.fruchterman_reingold_layout(G, k = self.kValue, iterations = self.MaxIterValue, scale = self.scaleValue, pos = originalPos, weight=1))
                positions = np.array(list(pos.values()))
                minX = 0
                minY = 0
                for p in positions:
                    if p[0] < minX:
                        minX = p[0]
                    if p[1] < minY:
                        minY = p[1]
                positions = positions - np.array([minX, minY])
                centroids = positions[0: len(reactionsInd)]
                nodes = positions[len(reactionsInd): len(positions)]
                count = 0
                for n in nodes:
                    newX = float(n[0])
                    newY = float(n[1])
                    api.move_node(0, nodesInd[count], position = Vec2(newX, newY), allowNegativeCoordinates=True)   
                    count = count + 1
                
                if self.useCentroid:
                    count = 0
                    for c in centroids:
                        newX = float(c[0])
                        newY = float(c[1])
                        r = api.get_reaction_by_index(0, reactionsInd[count])
                        handles = api.default_handle_positions(0, r.index)
                        api.update_reaction(0, r.index, center_pos=Vec2(newX, newY), handle_positions=handles)  
                        count = count + 1
                else:
                    for index in api.get_reaction_indices(0):
                        api.update_reaction(0, index, center_pos=None)
                        handles = api.default_handle_positions(0, index)
                        api.update_reaction(0, index, handle_positions=handles)

                '''
                
                for r in api.get_reactions(0):
                    currCentroid = centroids[r.index]
                    newX = float(currCentroid[0])
                    newY = float(currCentroid[1])
                    api.update_reaction(0, r.index, center_pos=(Vec2(newX, newY)))
                    #api.update_reaction(0, r.index, center_pos=None)
                    handles = api.default_handle_positions(0, r.index)
                    api.set_reaction_center_handle(0, r.index, handles[0])
                    count = 1
                    for s in r.sources:
                        api.set_reaction_node_handle(0, r.index, s, True, handles[count])
                        count += 1
                    for t in r.targets:
                        api.set_reaction_node_handle(0, r.index, t, False, handles[count])
                        count += 1
                
                '''

            ws = api.window_size()
            offset = Vec2(ws.x/4, ws.y/4)
            api.translate_network(0, offset, check_bounds = True)
コード例 #7
0
ファイル: addReaction.py プロジェクト: nnguyen19/PyRKViewer
class AddReaction(WindowedPlugin):
   metadata = PluginMetadata(
      name='AddReaction',
      author='Jin Xu and Herbert Sauro',
      version='0.0.1',
      short_desc='Add Reactions.',
      long_desc='Add different reactions including UniUni, BiUni, UniBi and BiBi.',
      category=PluginCategory.UTILITIES,
   )
   def __init__(self):
      """
      Initialize the StructuralAnalysis Plugin.
      Args:
         self
      """
      super().__init__()
      self.uniuniState = False
      self.biuniState = False
      self.unibiState = False
      self.bibiState = False
      self.src = []
      self.dest = []

   def create_window(self, dialog):
      """
      Create a window to do the structural analysis.
      Args:
         self
         dialog
      """
      window = wx.Panel(dialog, pos=(5,100), size=(150, 190))

      wx.StaticText(window, -1, 'Select reaction type', (15,10))
      wx.StaticText(window, -1, 'then select nodes:', (15,25))

      self.UniUni_btn = wx.ToggleButton(window, -1, 'UniUni', (36, 22+25), size=(62,22))
      self.UniUni_btn.Bind(wx.EVT_TOGGLEBUTTON, self.UniUni)

      self.BiUni_btn = wx.ToggleButton(window, -1, 'BiUni', (36, 47+25), size=(62,22))
      self.BiUni_btn.Bind(wx.EVT_TOGGLEBUTTON, self.BiUni)

      self.UniBi_btn = wx.ToggleButton(window, -1, 'UniBi', (36, 72+25), size=(62,22))
      self.UniBi_btn.Bind(wx.EVT_TOGGLEBUTTON, self.UniBi)

      self.BiBi_btn = wx.ToggleButton(window, -1, 'BiBi', (36, 97+25), size=(62,22))
      self.BiBi_btn.Bind(wx.EVT_TOGGLEBUTTON, self.BiBi)

      window.SetPosition (wx.Point(10,10))
      return window

   def on_did_create_dialog(self):
      # Set position of popup window to top-left corner of screen
      self.dialog.SetPosition((240, 250))

   def on_will_close_window(self, evt):
      # print ("***** Window Closed *****") 
      evt.Skip()

   def getUniqueName(self, base: str, names: list) -> str:
      increment = 0
      # keep incrementing until you find a unique Id
      while True:
         suffix = '_{}'.format(increment)

         cur_id = base + suffix

         if cur_id in names:
               increment += 1
               continue
         else:
               # loop finished normally; done
               return cur_id

   def addReaction (self, src, dest):
      # THis method is callde for all reactions
      names = []
      # Get a unique reaction name
      for r in api.get_reactions (0):
         names.append (r.id)          
      reactionId = self.getUniqueName('reaction', names)
      r_idx = api.add_reaction(0, reactionId, src, dest, fill_color=api.Color(129, 123, 255))

   def on_selection_did_change(self, evt):
      """
      Overrides base class event handler to update number of items selected.
      Args:
         self
         node_indices(List[int]): List of node indices changed.
         reaction_indices (List[int]): List of reaction indices changed.
         compartment_indices (List[int]): List of compartment indices changed.
      """
      if len (list(evt.node_indices)) == 0:
         self.src = []
         self.dest = []
         return

      if (not self.uniuniState) and (not self.biuniState) and \
            (not self.unibiState) and (not self.bibiState):
         return

      self.node_clicked = list(evt.node_indices)
      
      try:
         if self.uniuniState:
            if len(self.src) == 0:
               self.src.append (self.node_clicked[0])
               return

            if len (self.dest) == 0:
               self.dest.append (self.node_clicked[0])
               self.addReaction (self.src, self.dest)
               return

         if self.biuniState:
            if len(self.src) == 0:
               self.src.append (self.node_clicked[0])
               return

            if len (self.src) == 1:
               self.src.append (self.node_clicked[0])
               return

            if (len (self.src) <= 2) and len (self.dest) == 0:
               self.dest.append (self.node_clicked[0])
               self.addReaction (self.src, self.dest)
               return          

         if self.unibiState:
            if len(self.src) == 0:
               self.src.append (self.node_clicked[0])
               return

            if len (self.dest) == 0:
               self.dest.append (self.node_clicked[0])
               return
            
            if (len (self.src) <= 1) and len (self.dest) == 1:
               self.dest.append (self.node_clicked[0])
               self.addReaction (self.src, self.dest)
               return

         if self.bibiState:
            if len(self.src) == 0:
               self.src.append (self.node_clicked[0])
               return

            if len (self.src) == 1:
               self.src.append (self.node_clicked[0])
               return

            if len (self.dest) == 0:
               self.dest.append (self.node_clicked[0])
               return

            if (len (self.src) <= 2) and len (self.dest) == 1:
               self.dest.append (self.node_clicked[0])
               self.addReaction (self.src, self.dest)
               return
      except:
         pass #wx.MessageBox("Error: Try again", "Message", wx.OK | wx.ICON_INFORMATION)

   def UniUni(self, evt):
      """
      Handler for the "UniUni" button. add a UniUni reaction.
      """
      state = evt.GetEventObject().GetValue()
      if state == True:  
         self.src = []
         self.dest = []
         # This code is to make the buttons work as a radionbutton
         self.uniuniState = True
         self.biuniState = False
         self.unibiState = False
         self.bibiState = False
         self.BiUni_btn.SetValue (False)
         self.UniBi_btn.SetValue (False)
         self.BiBi_btn.SetValue (False)            
      else:
         self.uniuniState = False

   def BiUni(self, evt):
      """
      Handler for the "BiUni" button. add a BiUni reaction.
      """
      state = evt.GetEventObject().GetValue()
      if state == True:  
         self.src = []
         self.dest = []

         # This code is to make the buttons work as a radionbutton
         self.uniuniState = False
         self.biuniState = True
         self.unibiState = False
         self.bibiState = False  
         self.UniUni_btn.SetValue (False)          
         self.UniBi_btn.SetValue (False)
         self.BiBi_btn.SetValue (False)  
      else:
         self.biuniState = False


   def UniBi(self, evt):
      """
      Handler for the "UniBi" button. add a UniBi reaction.
      """
      state = evt.GetEventObject().GetValue()
      if state == True:  
         self.src = []
         self.dest = []

         # This code is to make the buttons work as a radionbutton          
         self.uniuniState = False
         self.biuniState = False
         self.unibiState = True
         self.bibiState = False  
         self.UniUni_btn.SetValue (False)          
         self.BiUni_btn.SetValue (False)
         self.BiBi_btn.SetValue (False)                        
      else:
         self.unibiState = False

   def BiBi(self, evt):
      """
      Handler for the "UniBi" button. add a UniBi reaction.
      """
      state = evt.GetEventObject().GetValue()
      if state == True:  
         self.src = []
         self.dest = []

         # This code is to make the buttons work as a radionbutton
         self.uniuniState = False
         self.biuniState = False
         self.unibiState = False
         self.bibiState = True
         self.UniUni_btn.SetValue (False)          
         self.BiUni_btn.SetValue (False)
         self.UniBi_btn.SetValue (False)                        
      else:
         self.bibiState = False
コード例 #8
0
class StructuralAnalysis(WindowedPlugin):
    metadata = PluginMetadata(
        name='StructuralAnalysis',
        author='Jin Xu',
        version='0.0.1',
        short_desc='Structural Analysis.',
        long_desc=
        'StructuralAnalysis Plugin is to calculate and visualize the stoichiometry matrix and conserved moieties for the network.',
        category=PluginCategory.ANALYSIS)

    def __init__(self):
        """
        Initialize the StructuralAnalysis Plugin.
        Args:
            self
        """
        super().__init__()
        self.index_list = []

    def create_window(self, dialog):
        """
        Create a window to do the structural analysis.
        Args:
            self
            dialog
        """
        topPanel = wx.Panel(dialog, pos=(0, 0), size=(700, 500))

        # Create two panels size by side
        panel1 = wx.Panel(topPanel, -1, pos=(0, 100), size=(200, 100))
        panel2 = wx.Panel(topPanel, -1, pos=(100, 100), size=(450, 100))

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(panel1, 0, wx.EXPAND | wx.ALL, border=10)
        sizer.Add(panel2, 0, wx.EXPAND | wx.ALL, border=10)

        topPanel.SetSizer(sizer)

        # Add a notebook to the second panel
        nb = wx.Notebook(panel2)

        # Create the tabs
        self.tab1 = TabOne(nb)
        self.tab2 = TabTwo(nb)
        nb.AddPage(self.tab1, "Stoichiometry")
        nb.AddPage(self.tab2, "Moiety Conservation Laws")

        # Make sure the second panel fills the right side.
        sizer = wx.BoxSizer()
        sizer.Add(nb, 1, wx.EXPAND)
        panel2.SetSizer(sizer)

        Compute_btn = wx.Button(panel1, -1, 'Compute Conservation Laws',
                                (20, 20))
        Compute_btn.Bind(wx.EVT_BUTTON, self.Compute)

        wx.StaticText(panel1, -1, 'Select a row from the table of', (20, 100))
        wx.StaticText(panel1, -1, 'Moiety Conservation Laws', (20, 120))
        wx.StaticText(panel1, -1, 'and pick a color:', (20, 140))

        Picker = wx.ColourPickerCtrl(panel1, pos=(20, 160))
        Picker.Bind(wx.EVT_COLOURPICKER_CHANGED, self.color_callback)

        wx.StaticText(panel1, -1, 'Unhighlight the nodes:', (20, 240))
        Clear_Btn = wx.Button(panel1, -1, 'Clear', (20, 260))
        Clear_Btn.Bind(wx.EVT_BUTTON, self.unhighlight)

        return topPanel

    def on_did_create_dialog(self):
        # Set position of popup window to top-left corner of screen
        self.dialog.SetPosition((240, 250))

    def Compute(self, evt):
        """
        Handler for the "Compute" button.
        Get the network on canvas.
        Calculate the Stoichiometry Matrix and Conservation Matrix for the randon network.
        """

        #self.index_list=[]

        def nullspace(A, atol=1e-13, rtol=0):
            A = _np.atleast_2d(A)
            u, s, vh = _np.linalg.svd(A)
            tol = max(atol, rtol * s[0])
            nnz = (s >= tol).sum()
            ns = vh[nnz:].conj().T
            return ns

        def rref(B, tol=1e-8, debug=False):
            A = B.copy()
            rows, cols = A.shape
            r = 0
            pivots_pos = []
            row_exchanges = _np.arange(rows)
            for c in range(cols):
                if debug:
                    print("Now at row", r, "and col", c, "with matrix:")
                    print(A)

                ## Find the pivot row:
                pivot = _np.argmax(_np.abs(A[r:rows, c])) + r
                m = _np.abs(A[pivot, c])
                if debug: print("Found pivot", m, "in row", pivot)
                if m <= tol:
                    ## Skip column c, making sure the approximately zero terms are
                    ## actually zero.
                    A[r:rows, c] = _np.zeros(rows - r)
                    if debug:
                        print("All elements at and below (", r, ",", c,
                              ") are zero.. moving on..")
                else:
                    ## keep track of bound variables
                    pivots_pos.append((r, c))

                    if pivot != r:
                        ## Swap current row and pivot row
                        A[[pivot, r], c:cols] = A[[r, pivot], c:cols]
                        row_exchanges[[pivot, r]] = row_exchanges[[r, pivot]]

                        if debug:
                            print("Swap row", r, "with row", pivot, "Now:")
                            print(A)

                    ## Normalize pivot row
                    A[r, c:cols] = A[r, c:cols] / A[r, c]

                    ## Eliminate the current column
                    v = A[r, c:cols]
                    ## Above (before row r):
                    if r > 0:
                        ridx_above = _np.arange(r)
                        A[ridx_above,
                          c:cols] = A[ridx_above, c:cols] - _np.outer(
                              v, A[ridx_above, c]).T
                        if debug:
                            print("Elimination above performed:")
                            print(A)
                    ## Below (after row r):
                    if r < rows - 1:
                        ridx_below = _np.arange(r + 1, rows)
                        A[ridx_below,
                          c:cols] = A[ridx_below, c:cols] - _np.outer(
                              v, A[ridx_below, c]).T
                        if debug:
                            print("Elimination below performed:")
                            print(A)
                    r += 1
                ## Check if done
                if r == rows:
                    break
            return (A, pivots_pos, row_exchanges)

        netIn = 0
        numNodes = api.node_count(netIn)

        if numNodes == 0:
            wx.MessageBox("Please import a network on canvas", "Message",
                          wx.OK | wx.ICON_INFORMATION)
        else:
            allNodes = api.get_nodes(netIn)
            id = allNodes[0].id[0:-2]
            self.default_color = allNodes[0].fill_color

            largest_node_index = 0
            for i in range(numNodes):
                if allNodes[i].index > largest_node_index:
                    largest_node_index = allNodes[i].index
            row = largest_node_index + 1
            numReactions = api.reaction_count(netIn)
            #print("numReactions:", numReactions)
            col = numReactions
            self.st = _np.zeros((row, col))
            allReactions = api.get_reactions(netIn)
            for i in range(numReactions):
                for j in range(len(allReactions[i].sources)):
                    #print(allReactions[i].sources[j])
                    for m in range(row):
                        if allReactions[i].sources[j] == m:
                            self.st.itemset((m, i), -1)
                for j in range(len(allReactions[i].targets)):
                    #print(allReactions[i].targets[j])
                    for m in range(row):
                        if allReactions[i].targets[j] == m:
                            self.st.itemset((m, i), 1)

            stt = _np.transpose(self.st)
            m = _np.transpose(nullspace(stt))
            moi_mat = rref(m)[0]
            # set all the values of non-existing nodes to zero
            for i in range(moi_mat.shape[0]):
                for j in range(moi_mat.shape[1]):
                    if _np.array_equal(self.st[j, :],
                                       _np.zeros(self.st.shape[1])):
                        moi_mat.itemset((i, j), 0.)

            for i in range(self.st.shape[1]):
                self.tab1.grid_st.SetColLabelValue(i, "J" + str(i))
            for i in range(self.st.shape[0]):
                self.tab1.grid_st.SetRowLabelValue(i, id + "_" + str(i))

            for row in range(self.st.shape[0]):
                for col in range(self.st.shape[1]):
                    self.tab1.grid_st.SetCellValue(
                        row, col, "%d" % self.st.item(row, col))

            for i in range(moi_mat.shape[1]):
                self.tab2.grid_moi.SetColLabelValue(i, id + "_" + str(i))

            CSUM_id = 0
            for i in range(moi_mat.shape[0]):
                a = moi_mat[i, :]
                a = [0 if a_ < 0.005 else a_
                     for a_ in a]  # some elements are very small
                if _np.array_equal(
                        a, _np.zeros(moi_mat.shape[1])
                ):  # delete the row if all the elements are zero
                    CSUM_id = CSUM_id
                else:
                    self.tab2.grid_moi.SetRowLabelValue(
                        CSUM_id, "CSUM" + str(CSUM_id))

                    for j in range(moi_mat.shape[1]):
                        self.tab2.grid_moi.SetCellValue(
                            CSUM_id, j, format(moi_mat[i][j], ".2f"))  #

                    CSUM_id += 1

    def printSelectedCells(self, top_left, bottom_right):
        """
        Based on code from http://ginstrom.com/scribbles/2008/09/07/getting-the-selected-cells-from-a-wxpython-grid/
        """
        cells = []

        rows_start = top_left[0]
        rows_end = bottom_right[0]
        cols_start = top_left[1]
        cols_end = bottom_right[1]
        rows = range(rows_start, rows_end + 1)
        cols = range(cols_start, cols_end + 1)
        cells.extend([(row, col) for row in rows for col in cols])

        #self.index_list = []
        for cell in cells:
            row, col = cell
            value = self.tab2.grid_moi.GetCellValue(row, col)
            #print(value)
            if value != "0.00" and value != "+0.00" and value != "-0.00" and value != "":
                self.index_list.append(int(col))
            #print("selected nodes:", self.index_list)

    def color_callback(self, evt):
        """
        Get whatever cells are currently selected
        """

        cells = self.tab2.grid_moi.GetSelectedCells()
        if not cells:
            if self.tab2.grid_moi.GetSelectionBlockTopLeft():
                top_left = self.tab2.grid_moi.GetSelectionBlockTopLeft()[0]
                bottom_right = self.tab2.grid_moi.GetSelectionBlockBottomRight(
                )[0]
                self.printSelectedCells(top_left, bottom_right)
            #else:
            #    print (self.currentlySelectedCell)
        else:
            print("no cells are selected")
        """
        Callback for the color picker control; sets the color of every node/reaction selected.
        """

        wxcolor = evt.GetColour()
        color = Color.from_rgb(wxcolor.GetRGB())

        # start group action context for undo purposes
        with api.group_action():
            # color selected nodes
            #for index in api.selected_node_indices():

            if len(self.index_list) == 0:
                wx.MessageBox("Please select a row and pick a color again",
                              "Message", wx.OK | wx.ICON_INFORMATION)
            try:
                for index in self.index_list:
                    api.update_node(api.cur_net_index(),
                                    index,
                                    fill_color=color,
                                    border_color=color)
            except:
                wx.MessageBox("Please select a row and pick a color again",
                              "Message", wx.OK | wx.ICON_INFORMATION)

    def unhighlight(self, evt):
        """
        Callback for the color picker control; sets the color of every node/reaction selected.
        """

        # start group action context for undo purposes
        with api.group_action():
            # color selected nodes
            #for index in api.selected_node_indices():
            try:
                for index in self.index_list:
                    api.update_node(api.cur_net_index(),
                                    index,
                                    fill_color=self.default_color,
                                    border_color=self.default_color)
            except:
                wx.MessageBox("There is no highlighted nodes", "Message",
                              wx.OK | wx.ICON_INFORMATION)
コード例 #9
0
ファイル: randomNetwork.py プロジェクト: nnguyen19/PyRKViewer
class RandomNetwork(WindowedPlugin):
    metadata = PluginMetadata(
        name='RandomNetwork',
        author='Jin Xu, Herbert M Sauro',
        version='0.0.1',
        short_desc='Random network.',
        long_desc='Display a random network with certain number of species and reactions as input.',
        category=PluginCategory.UTILITIES
    )
    def __init__(self):
        """
        Initialize the RandomNetwork.

        Args:
            self

        """
        super().__init__()
        

    def create_window(self, dialog):
        """
        Create a window with several inputs and buttons.
        Args:
            self
            dialog
        """

        window = wx.Panel(dialog, pos=(5,100), size=(300, 320))

        numSpecs = wx.StaticText(window, -1, 'Number of Species:', (20,20))
        self.numSpecsText = wx.TextCtrl(window, -1, str(DefaultValues.maxSpecies), (160, 20), size=(100, -1))
        self.numSpecsText.SetInsertionPoint(0)
        self.numSpecsText.Bind(wx.EVT_TEXT, self.OnText_numSpecs)
        self.numSpecsValue = int(self.numSpecsText.GetValue())
       
        numRxns = wx.StaticText(window, -1, 'Number of Reactions:', (20,50))
        self.numRxnsText = wx.TextCtrl(window, -1, str(DefaultValues.maxReactions), (160, 50), size=(100, -1))
        self.numRxnsText.SetInsertionPoint(0)
        self.numRxnsText.Bind(wx.EVT_TEXT, self.OnText_numRxns)
        self.numRxnsValue = int(self.numRxnsText.GetValue())  
 
        probUniUni = wx.StaticText(window, -1, 'Probability of UniUni:', (20,90))      
        self.probUniUniText = wx.TextCtrl(window, -1, str(DefaultValues.probUniUniValue), (160, 90), size=(100, -1))
        self.probUniUniText.SetInsertionPoint(0)
        self.probUniUniText.Bind(wx.EVT_TEXT, self.OnText_UniUni)
        self.probUniUniValue = float(self.probUniUniText.GetValue())        
 
        probBiUni = wx.StaticText(window, -1, 'Probability of BiUni:', (20,120))
        self.probBiUniText = wx.TextCtrl(window, -1, str(DefaultValues.probBiUniValue), (160, 120), size=(100, -1))
        self.probBiUniText.SetInsertionPoint(0)
        self.probBiUniText.Bind(wx.EVT_TEXT, self.OnText_BiUni)
        self.probBiUniValue = float(self.probBiUniText.GetValue())

        probUniBi = wx.StaticText(window, -1, 'Probability of UniBi:', (20,150))
        self.probUniBiText = wx.TextCtrl(window, -1, str(DefaultValues.probUniBiValue), (160, 150), size=(100, -1))
        self.probUniBiText.SetInsertionPoint(0)
        self.probUniBiText.Bind(wx.EVT_TEXT, self.OnText_UniBi)
        self.probUniBiValue = float(self.probUniBiText.GetValue())

        probBiBi = wx.StaticText(window, -1, 'Probability of BiBi:', (20,180))
        self.probBiBiText = wx.TextCtrl(window, -1, str(DefaultValues.probBiBiValue), (160, 180), size=(100, -1))
        self.probBiBiText.SetInsertionPoint(0)
        self.probBiBiText.Bind(wx.EVT_TEXT, self.OnText_BiBi)
        self.probBiBiValue = float(self.probBiBiText.GetValue())

        randomSeed = wx.StaticText(window, -1, 'Random seed:', (20,210))
        randomSeed = wx.StaticText(window, -1, '0 means no seed setup', (20,230))
        self.randomSeedText = wx.TextCtrl(window, -1, str(DefaultValues.randomSeed), (160, 210), size=(100, -1))
        self.randomSeedText.SetInsertionPoint(0)
        self.randomSeedText.Bind(wx.EVT_TEXT, self.OnText_randomSeed)
        self.randomSeedValue = float(self.randomSeedText.GetValue())
 
        apply_btn = wx.Button(window, -1, 'Apply', (160, 250))
        apply_btn.Bind(wx.EVT_BUTTON, self.Apply)

        return window


    def OnText_numSpecs(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.numSpecsValue = int(self.numSpecsText.GetValue())
            except:
                wx.MessageBox("Please enter an integer for the number of species.", "Message", wx.OK | wx.ICON_INFORMATION)


    def OnText_numRxns(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.numRxnsValue = int(self.numRxnsText.GetValue())
            except:
                wx.MessageBox("Please enter an integer for the number of reactions.", "Message", wx.OK | wx.ICON_INFORMATION)

 
    def OnText_UniUni(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.probUniUniValue = float(self.probUniUniText.GetValue())
            except:
                wx.MessageBox("Please enter a floating point number for the probability of UniUni.", "Message", wx.OK | wx.ICON_INFORMATION)


    def OnText_BiUni(self, evt):
        update = evt.GetString()
        if update != '':
            #DefaultValues.probBiUniValue = float(self.probBiUniText.GetValue())
            try:
                self.probBiUniValue = float(self.probBiUniText.GetValue())
            except:
                wx.MessageBox("Please enter a floating point number for the probability of BiUni.", "Message", wx.OK | wx.ICON_INFORMATION)

    def OnText_UniBi(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.probUniBiValue = float(self.probUniBiText.GetValue())
            except:
                wx.MessageBox("Please enter a floating point number for the probability of UniBi.", "Message", wx.OK | wx.ICON_INFORMATION)


    def OnText_BiBi(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.probBiBiValue = float(self.probBiBiText.GetValue())
            except:
                wx.MessageBox("Please enter a floating point number for the probability of BiBi.", "Message", wx.OK | wx.ICON_INFORMATION)

    def OnText_randomSeed(self, evt):
        update = evt.GetString()
        if update != '':
            try:
                self.randomSeedValue = float(self.randomSeedText.GetValue())
            except:
                wx.MessageBox("Please enter a valid random seed other than zero.", "Message", wx.OK | wx.ICON_INFORMATION)


    def Apply(self, evt):
        """
        Handler for the "apply" button. apply the random network.
        """
        if self.randomSeedValue != 0:
            _random.seed(self.randomSeedValue)

        class _TReactionType:
            UNIUNI = 0
            BIUNI = 1
            UNIBI = 2
            BIBI = 3

        def _pickReactionType():

            rt = _random.random()
            if rt < self.probUniUniValue:
                return _TReactionType.UNIUNI
            elif rt < self.probUniUniValue + self.probBiUniValue:
                return _TReactionType.BIUNI
            elif rt < self.probUniUniValue + self.probBiUniValue + self.probUniBiValue:
                return _TReactionType.UNIBI
            else:
                return _TReactionType.BIBI


        # Generates a reaction network in the form of a reaction list
        # reactionList = [nSpecies, reaction, reaction, ....]
        # reaction = [reactionType, [list of reactants], [list of products], rateConsta>
        # Disallowed reactions:
        # S1 -> S1
        # S1 + S2 -> S2  # Can't have the same reactant and product
        # S1 + S1 -> S1
        def _generateReactionList (nSpecies, nReactions):

            reactionList = []
            for r in range(nReactions):
       
                rateConstant = _random.random()
                rt = _pickReactionType()
                if rt ==  _TReactionType.UNIUNI:
                    # UniUni
                    reactant = _random.randint (0, nSpecies-1)
                    product = _random.randint (0, nSpecies-1)
                    # Disallow S1 -> S1 type of reaction
                    while product == reactant:
                        product = _random.randint (0, nSpecies-1)
                    reactionList.append ([rt, [reactant], [product], rateConstant])
               
                if rt ==  _TReactionType.BIUNI:
                    # BiUni
                    # Pick two reactants
                    reactant1 = _random.randint (0, nSpecies-1)
                    reactant2 = _random.randint (0, nSpecies-1)
               
                    # pick a product but only products that don't include the reactants
                    species = range (nSpecies)
                    # Remove reactant1 and 2 from the species list
                    species = _np.delete (species, [reactant1, reactant2], axis=0)
                    # Then pick a product from the reactants that are left
                    product = species[_random.randint (0, len (species)-1)]
               
                    reactionList.append ([rt, [reactant1, reactant2], [product], rateConstant])

                if rt ==  _TReactionType.UNIBI:
                    # UniBi
                    reactant1 = _random.randint (0, nSpecies-1)
           
               
                    # pick a product but only products that don't include the reactant
                    species = range (nSpecies)
                    # Remove reactant1 from the species list
                    species = _np.delete (species, [reactant1], axis=0)
                    # Then pick a product from the reactants that are left
                    product1 = species[_random.randint (0, len (species)-1)]
                    product2 = species[_random.randint (0, len (species)-1)]
   
                    reactionList.append ([rt, [reactant1], [product1, product2], rateConstant])

                if rt ==  _TReactionType.BIBI:
                    # BiBi
                    reactant1 = _random.randint (0, nSpecies-1)
                    reactant2= _random.randint (0, nSpecies-1)
               
                    # pick a product but only products that don't include the reactant
                    species = range (nSpecies)
                    # Remove reactant1 and 2 from the species list
                    species = _np.delete (species, [reactant1, reactant2], axis=0)
                    # Then pick a product from the reactants that are left
                    product1 = species[_random.randint (0, len (species)-1)]
                    product2 = species[_random.randint (0, len (species)-1)]
               
                    element = [rt, [reactant1, reactant2], [product1, product2], rateConstant]
                    reactionList.append (element)            

            reactionList.insert (0, nSpecies)
            return reactionList



        # Includes boundary and floating species
        # Returns a list:
        # [New Stoichiometry matrix, list of floatingIds, list of boundaryIds]
        def _getFullStoichiometryMatrix (reactionList):
     
            nSpecies = reactionList[0]
            reactionListCopy = _copy.deepcopy (reactionList)
            reactionListCopy.pop (0)
            st = _np.zeros ((nSpecies, len(reactionListCopy)))
   
            for index, r in enumerate (reactionListCopy):
                if r[0] ==  _TReactionType.UNIUNI:
                    # UniUni
                    reactant = reactionListCopy[index][1][0]
                    st[reactant, index] = -1
                    product = reactionListCopy[index][2][0]
                    st[product, index] = 1
     
                if r[0] ==  _TReactionType.BIUNI:
                    # BiUni
                    reactant1 = reactionListCopy[index][1][0]
                    st[reactant1, index] = -1
                    reactant2 = reactionListCopy[index][1][1]
                    st[reactant2, index] = -1
                    product = reactionListCopy[index][2][0]
                    st[product, index] = 1

                if r[0] ==  _TReactionType.UNIBI:
                    # UniBi
                    reactant1 = reactionListCopy[index][1][0]
                    st[reactant1, index] = -1
                    product1 = reactionListCopy[index][2][0]
                    st[product1, index] = 1
                    product2 = reactionListCopy[index][2][1]
                    st[product2, index] = 1
 
                if r[0] ==  _TReactionType.BIBI:
                    # BiBi
                    reactant1 = reactionListCopy[index][1][0]
                    st[reactant1, index] = -1
                    reactant2 = reactionListCopy[index][1][1]
                    st[reactant2, index] = -1
                    product1 = reactionListCopy[index][2][0]
                    st[product1, index] = 1
                    product2 = reactionListCopy[index][2][1]
                    st[product2, index] = 1

            return st

        def _getRateLaw (floatingIds, boundaryIds, reactionList, isReversible):
   
            nSpecies = reactionList[0]
            # Remove the first element which is the nSpecies
            reactionListCopy = _copy.deepcopy (reactionList)
            reactionListCopy.pop (0)

            antStr_tot = []

            for index, r in enumerate (reactionListCopy):
                antStr= ''
                antStr = antStr + 'J' + str (index) + ': '
                if r[0] == _TReactionType.UNIUNI:
                    # UniUni
                    antStr = antStr + '(k' + str (index) + '*S' + str (reactionListCopy[index][1][0])
                    if isReversible:
                        antStr = antStr + ' - k' + str (index) + 'r' + '*S' + str (reactionListCopy[index][2][0])
                    antStr = antStr + ')'
                if r[0] == _TReactionType.BIUNI:
                    # BiUni
                    antStr = antStr + '(k' + str (index) + '*S' + str (reactionListCopy[index][1][0]) + '*S' + str (reactionListCopy[index][1][1])
                    if isReversible:
                        antStr = antStr + ' - k' + str (index) + 'r' + '*S' + str (reactionListCopy[index][2][0])
                    antStr = antStr + ')'
                if r[0] == _TReactionType.UNIBI:
                    # UniBi
                    antStr = antStr + '(k' + str (index) + '*S' + str (reactionListCopy[index][1][0])
                    if isReversible:
                        antStr = antStr + ' - k' + str (index) + 'r' + '*S' + str (reactionListCopy[index][2][0]) + '*S' + str (reactionListCopy[index][2][1])
                    antStr = antStr + ')'
                if r[0] == _TReactionType.BIBI:
                    # BiBi
                    antStr = antStr + '(k' + str (index) + '*S' + str (reactionListCopy[index][1][0]) + '*S' + str (reactionListCopy[index][1][1])
                    if isReversible:
                        antStr = antStr + ' - k' + str (index) + 'r' + '*S' + str (reactionListCopy[index][2][0]) + '*S' + str (reactionListCopy[index][2][1])
                    antStr = antStr + ')'
 
                antStr_tot.append(antStr)

            return antStr_tot      

        test_prob = self.probUniUniValue + self.probBiUniValue + self.probUniBiValue + self.probBiBiValue
	
        if test_prob != 1:
            wx.MessageBox("The sum of probabilities should be one!", "Message", wx.OK | wx.ICON_INFORMATION)

        else:
            net_index = 0
            api.clear_network(net_index)

            rl = _generateReactionList (self.numSpecsValue, self.numRxnsValue)
            st = _getFullStoichiometryMatrix (rl)
            antStr = _getRateLaw (st[1], st[2], rl, isReversible=True)
            numNodes = st.shape[0]
            numRxns = st.shape[1]

            nodeIdx = []
            for i in range (numNodes):
                nodeIdx.append (api.add_node(net_index, 'node_{}'.format(i), size=Vec2(60,40), fill_color=api.Color(255, 204, 153),
                        border_color=api.Color(255, 108, 9),
                        position=Vec2(40 + math.trunc (_random.random()*800), 40 + math.trunc (_random.random()*800))))
        
            for i in range (numRxns):
                src = []
                dest = []
            
                for j in range(numNodes):
                    if (st.item(j,i) == -1):
                        src.append(nodeIdx[j])  
                    if (st.item(j,i) == 1):
                        dest.append(nodeIdx[j])
                r_idx = api.add_reaction(net_index, 'reaction_{}'.format(i), src, dest, fill_color=api.Color(91, 176, 253))
            
            # Need to remove orphan nodes
            for i in range (numNodes):
                if _np.array_equal(st[i,:], _np.zeros(numRxns)):
                    api.delete_node(net_index, nodeIdx[i])
コード例 #10
0
class ExportSBML(WindowedPlugin):
    metadata = PluginMetadata(
        name='ExportSBML',
        author='Jin Xu',
        version='0.0.2',
        short_desc='Export SBML.',
        long_desc=
        'Export the SBML String from the network on canvas and save it to a file.',
        category=PluginCategory.ANALYSIS)

    def create_window(self, dialog):
        """
        Create a window to export the SBML.
        Args:
            self
            dialog
        """
        self.window = wx.Panel(dialog, pos=(5, 100), size=(300, 320))

        export_btn = wx.Button(self.window, -1, 'Export', (5, 5))
        export_btn.Bind(wx.EVT_BUTTON, self.Export)

        save_btn = wx.Button(self.window, -1, 'Save', (100, 5))
        save_btn.Bind(wx.EVT_BUTTON, self.Save)

        wx.StaticText(self.window, -1, 'SBML string:', (5, 30))
        self.SBMLText = wx.TextCtrl(self.window,
                                    -1,
                                    "", (10, 50),
                                    size=(260, 220),
                                    style=wx.TE_MULTILINE)
        self.SBMLText.SetInsertionPoint(0)

        return self.window

    def Export(self, evt):
        """
        Handler for the "Export" button.
        Get the network on canvas and change it to an SBML string.
        """

        isReversible = True
        netIn = 0
        numNodes = api.node_count(netIn)
        numReactions = api.reaction_count(netIn)

        if numNodes == 0:  #or numReactions == 0 :
            wx.MessageBox("Please import a network on canvas", "Message",
                          wx.OK | wx.ICON_INFORMATION)
        else:
            allNodes = api.get_nodes(netIn)
            allReactions = api.get_reactions(netIn)
            allcompartments = api.get_compartments(netIn)
            numCompartments = len(allcompartments)
            #######################################

            # Creates an SBMLNamespaces object with the given SBML level, version
            # package name, package version.
            #
            # (NOTE) By default, the name of package (i.e. "layout") will be used
            # if the argument for the prefix is missing or empty. Thus the argument
            # for the prefix can be added as follows:
            #
            #    SBMLNamespaces sbmlns(3,1,"layout",1,"LAYOUT")
            #
            sbmlns = SBMLNamespaces(3, 1, "layout", 1)
            # create the document
            document = SBMLDocument(sbmlns)
            # set the "required" attribute of layout package  to "true"
            document.setPkgRequired("layout", False)

            # create the Model

            model = document.createModel()
            model.setId("Model_layout")
            document.setModel(model)

            # create the Compartment and species
            if numCompartments != 0:
                for i in range(numCompartments):
                    compartment = model.createCompartment()
                    comp_id = allcompartments[i].id
                    compartment.setId(comp_id)
                    compartment.setConstant(True)
                    for j in range(len(allcompartments[i].nodes)):
                        spec_id = allNodes[allcompartments[i].nodes[j]].id
                        species = model.createSpecies()
                        species.setId(spec_id)
                        species.setCompartment(comp_id)
                        species.setInitialConcentration(1.0)
                        species.setHasOnlySubstanceUnits(False)
                        species.setBoundaryCondition(False)
                        species.setConstant(False)
                        if allNodes[allcompartments[i].
                                    nodes[j]].floatingNode == False:
                            species.setBoundaryCondition(True)
            else:  #set default compartment
                compartment = model.createCompartment()
                comp_id = "c_0"
                compartment.setId(comp_id)
                compartment.setConstant(True)
                for i in range(numNodes):
                    spec_id = allNodes[i].id
                    species = model.createSpecies()
                    species.setId(spec_id)
                    species.setCompartment(comp_id)
                    species.setInitialConcentration(1.0)
                    species.setHasOnlySubstanceUnits(False)
                    species.setBoundaryCondition(False)
                    species.setConstant(False)
                    if allNodes[i].floatingNode == False:
                        species.setBoundaryCondition(True)
                        species.setConstant(True)

            # create reactions:
            for i in range(numReactions):
                reaction_id = allReactions[i].id
                rct = []  # id list of the rcts
                prd = []
                rct_num = len(allReactions[i].sources)
                prd_num = len(allReactions[i].targets)
                for j in range(rct_num):
                    rct.append(allNodes[allReactions[i].sources[j]].id)
                for j in range(prd_num):
                    prd.append(allNodes[allReactions[i].targets[j]].id)

                kinetic_law = ''
                parameter_list = []
                kinetic_law = kinetic_law + 'E' + str(i) + '*(k' + str(i)
                parameter_list.append('E' + str(i))
                parameter_list.append('k' + str(i))
                for j in range(rct_num):
                    kinetic_law = kinetic_law + '*' + rct[j]

                reaction = model.createReaction()
                reaction.setId(allReactions[i].id)
                reaction.setReversible(False)
                reaction.setFast(False)
                if isReversible:
                    reaction.setReversible(True)
                    kinetic_law = kinetic_law + ' - k' + str(i) + 'r'
                    parameter_list.append('k' + str(i) + 'r')
                    for j in range(prd_num):
                        kinetic_law = kinetic_law + '*' + prd[j]
                kinetic_law = kinetic_law + ')'
                for j in range(len(parameter_list)):
                    parameters = model.createParameter()
                    parameters.setId(parameter_list[j])
                    parameters.setValue(0.1)
                    parameters.setConstant(True)
                kinetics = reaction.createKineticLaw()
                kinetics.setFormula(kinetic_law)

                for j in range(rct_num):
                    reference = reaction.createReactant()
                    reference.setSpecies(rct[j])
                    ref_id = "SpecRef_" + reaction_id + "_rct" + str(j)
                    reference.setId(ref_id)
                    reference.setStoichiometry(1.)
                    reference.setConstant(False)

                for j in range(prd_num):
                    reference = reaction.createProduct()
                    reference.setSpecies(prd[j])
                    ref_id = "SpecRef_" + reaction_id + "_prd" + str(j)
                    reference.setId(ref_id)
                    reference.setStoichiometry(1.)
                    reference.setConstant(False)

            # create the Layout

            #
            # set the LayoutPkgNamespaces for Level 3 Version1 Layout Version 1
            #
            layoutns = LayoutPkgNamespaces(3, 1, 1)

            renderns = RenderPkgNamespaces(3, 1, 1)

            #
            # Get a LayoutModelPlugin object plugged in the model object.
            #
            # The type of the returned value of SBase::getPlugin() function is SBasePlugin, and
            # thus the value needs to be casted for the corresponding derived class.
            #

            mplugin = model.getPlugin("layout")

            # rPlugin = model.getPlugin("render")
            # if rPlugin is None:
            #   print("there is no render outside layout.")

            # lolPlugin = mplugin.getListOfLayouts().getPlugin("render")
            # if lolPlugin is None:
            #   print("there is no render info inside layout.")

            if mplugin is None:
                # print(
                #     "[Fatal Error] Layout Extension Level " + layoutns.getLevel() + " Version " + layoutns.getVersion() + " package version " + layoutns.getPackageVersion() + " is not registered.")
                # sys.exit(1)
                wx.MessageBox("There is no layout information.", "Message",
                              wx.OK | wx.ICON_INFORMATION)

            #
            # Creates a Layout object via LayoutModelPlugin object.
            #
            layout = mplugin.createLayout()
            layout.setId("Layout_1")
            layout.setDimensions(Dimensions(layoutns, 800.0, 800.0))
            # random network (40+800x, 40+800y)

            #create the CompartmentGlyph and SpeciesGlyphs

            if numCompartments != 0:
                for i in range(numCompartments):
                    comp_id = allcompartments[i].id

                    compartmentGlyph = layout.createCompartmentGlyph()
                    compG_id = "CompG_" + comp_id
                    compartmentGlyph.setId(compG_id)
                    compartmentGlyph.setCompartmentId(comp_id)
                    bb_id = "bb_" + comp_id
                    pos_x = allcompartments[i].position.x
                    pos_y = allcompartments[i].position.y
                    width = allcompartments[i].size.x
                    height = allcompartments[i].size.y
                    compartmentGlyph.setBoundingBox(
                        BoundingBox(layoutns, bb_id, pos_x, pos_y, width,
                                    height))
                    for j in range(len(allcompartments[i].nodes)):
                        spec_id = allNodes[allcompartments[i].nodes[j]].id
                        speciesGlyph = layout.createSpeciesGlyph()
                        specG_id = "SpecG_" + spec_id
                        speciesGlyph.setId(specG_id)
                        speciesGlyph.setSpeciesId(spec_id)
                        bb_id = "bb_" + spec_id
                        pos_x = allNodes[
                            allcompartments[i].nodes[j]].position.x
                        pos_y = allNodes[
                            allcompartments[i].nodes[j]].position.y
                        width = allNodes[allcompartments[i].nodes[j]].size.x
                        height = allNodes[allcompartments[i].nodes[j]].size.y
                        speciesGlyph.setBoundingBox(
                            BoundingBox(layoutns, bb_id, pos_x, pos_y, width,
                                        height))

                        textGlyph = layout.createTextGlyph()
                        textG_id = "TextG_" + spec_id
                        textGlyph.setId(textG_id)
                        bb_id = "bb_spec_text_" + spec_id
                        textGlyph.setBoundingBox(
                            BoundingBox(layoutns, bb_id, pos_x, pos_y, width,
                                        height))
                        textGlyph.setOriginOfTextId(specG_id)
                        textGlyph.setGraphicalObjectId(specG_id)
            else:  #there is no compartment
                for i in range(numNodes):
                    spec_id = allNodes[i].id
                    speciesGlyph = layout.createSpeciesGlyph()
                    specG_id = "SpecG_" + spec_id
                    speciesGlyph.setId(specG_id)
                    speciesGlyph.setSpeciesId(spec_id)
                    bb_id = "bb_" + spec_id
                    pos_x = allNodes[i].position.x
                    pos_y = allNodes[i].position.y
                    width = allNodes[i].size.x
                    height = allNodes[i].size.y
                    speciesGlyph.setBoundingBox(
                        BoundingBox(layoutns, bb_id, pos_x, pos_y, width,
                                    height))

                    textGlyph = layout.createTextGlyph()
                    textG_id = "TextG_" + spec_id
                    textGlyph.setId(textG_id)
                    bb_id = "bb_spec_text_" + spec_id
                    textGlyph.setBoundingBox(
                        BoundingBox(layoutns, bb_id, pos_x, pos_y, width,
                                    height))
                    textGlyph.setOriginOfTextId(specG_id)
                    textGlyph.setGraphicalObjectId(specG_id)

            # create the ReactionGlyphs and SpeciesReferenceGlyphs
            for i in range(numReactions):
                reaction_id = allReactions[i].id
                reactionGlyph = layout.createReactionGlyph()
                reactionG_id = "RectionG_" + reaction_id
                reactionGlyph.setId(reactionG_id)
                reactionGlyph.setReactionId(reaction_id)

                reactionCurve = reactionGlyph.getCurve()
                ls = reactionCurve.createLineSegment()
                centroid = api.compute_centroid(0, allReactions[i].sources,
                                                allReactions[i].targets)
                ls.setStart(Point(layoutns, centroid.x, centroid.y))
                ls.setEnd(Point(layoutns, centroid.x, centroid.y))

                rct = []  # id list of the rcts
                prd = []
                rct_num = len(allReactions[i].sources)
                prd_num = len(allReactions[i].targets)
                for j in range(rct_num):
                    rct.append(allNodes[allReactions[i].sources[j]].id)
                for j in range(prd_num):
                    prd.append(allNodes[allReactions[i].targets[j]].id)

                for j in range(rct_num):
                    ref_id = "SpecRef_" + reaction_id + "_rct" + str(j)

                    speciesReferenceGlyph = reactionGlyph.createSpeciesReferenceGlyph(
                    )
                    specsRefG_id = "SpecRefG_" + reaction_id + "_rct" + str(j)
                    specG_id = "SpecG_" + rct[j]
                    speciesReferenceGlyph.setId(specsRefG_id)
                    speciesReferenceGlyph.setSpeciesGlyphId(specG_id)
                    speciesReferenceGlyph.setSpeciesReferenceId(ref_id)
                    speciesReferenceGlyph.setRole(SPECIES_ROLE_UNDEFINED)

                    speciesReferenceCurve = speciesReferenceGlyph.getCurve()
                    cb = speciesReferenceCurve.createCubicBezier()
                    #cb = speciesReferenceCurve.createLineSegment()

                    cb.setStart(Point(layoutns, centroid.x, centroid.y))

                    handles = api.default_handle_positions(
                        netIn, allReactions[i].index)
                    pos_x = handles[1 + j].x
                    pos_y = handles[1 + j].y
                    cb.setBasePoint1(Point(layoutns, pos_x, pos_y))
                    cb.setBasePoint2(Point(layoutns, pos_x, pos_y))

                    pos_x = allNodes[allReactions[i].sources[j]].position.x
                    pos_y = allNodes[allReactions[i].sources[j]].position.y
                    width = allNodes[allReactions[i].sources[j]].size.x
                    height = allNodes[allReactions[i].sources[j]].size.y
                    cb.setEnd(
                        Point(layoutns, pos_x + 0.5 * width,
                              pos_y - 0.5 * height))

                for j in range(prd_num):
                    ref_id = "SpecRef_" + reaction_id + "_prd" + str(j)
                    speciesReferenceGlyph = reactionGlyph.createSpeciesReferenceGlyph(
                    )
                    specsRefG_id = "SpecRefG_" + reaction_id + "_prd" + str(j)
                    specG_id = "SpecG_" + prd[j]
                    speciesReferenceGlyph.setId(specsRefG_id)
                    speciesReferenceGlyph.setSpeciesGlyphId(specG_id)
                    speciesReferenceGlyph.setSpeciesReferenceId(ref_id)
                    speciesReferenceGlyph.setRole(SPECIES_ROLE_UNDEFINED)

                    speciesReferenceCurve = speciesReferenceGlyph.getCurve()
                    cb = speciesReferenceCurve.createCubicBezier()
                    #cb = speciesReferenceCurve.createLineSegment()
                    cb.setStart(Point(layoutns, centroid.x, centroid.y))

                    handles = api.default_handle_positions(
                        netIn, allReactions[i].index)
                    pos_x = handles[1 + j].x
                    pos_y = handles[1 + j].y
                    cb.setBasePoint1(Point(layoutns, pos_x, pos_y))
                    cb.setBasePoint2(Point(layoutns, pos_x, pos_y))

                    pos_x = allNodes[allReactions[i].targets[j]].position.x
                    pos_y = allNodes[allReactions[i].targets[j]].position.y
                    width = allNodes[allReactions[i].targets[j]].size.x
                    height = allNodes[allReactions[i].targets[j]].size.y
                    cb.setEnd(
                        Point(layoutns, pos_x + 0.5 * width,
                              pos_y - 0.5 * height))

            sbmlStr_layout = writeSBMLToString(
                document)  #sbmlStr is w/o layout info
            #self.SBMLText.SetValue(sbmlStr_layout)

            doc = readSBMLFromString(sbmlStr_layout)
            model_layout = doc.getModel()
            mplugin = model_layout.getPlugin("layout")

            # add render information to the first layout
            layout = mplugin.getLayout(0)

            rPlugin = layout.getPlugin("render")

            uri = RenderExtension.getXmlnsL2() if doc.getLevel(
            ) == 2 else RenderExtension.getXmlnsL3V1V1()

            # enable render package
            doc.enablePackage(uri, "render", True)
            doc.setPackageRequired("render", False)

            rPlugin = layout.getPlugin("render")

            rInfo = rPlugin.createLocalRenderInformation()
            rInfo.setId("info")
            rInfo.setName("Render Information")
            rInfo.setProgramName("RenderInformation")
            rInfo.setProgramVersion("1.0")

            # add some colors
            if numCompartments != 0:
                fill_color = allcompartments[0].fill_color
                border_color = allcompartments[0].border_color
                comp_border_width = allcompartments[0].border_width
                fill_color_str = '#%02x%02x%02x' % (fill_color.r, fill_color.g,
                                                    fill_color.b)
                border_color_str = '#%02x%02x%02x' % (
                    border_color.r, border_color.g, border_color.b)

            else:
                comp_border_width = 2.
                fill_color_str = '#9ea9ff'
                border_color_str = '#001dff'

            #nodeData does not have fill_color,border_color,border_width
            node = allNodes[0]
            # spec_fill_color   = node.fill_color
            # spec_border_color = node.border_color
            # spec_border_width = node.border_width
            # spec_fill_color_str   = '#%02x%02x%02x' % (spec_fill_color.r,spec_fill_color.g,spec_fill_color.b)
            # spec_border_color_str = '#%02x%02x%02x' % (spec_border_color.r,spec_border_color.g,spec_border_color.b)

            spec_fill_color_str = '#ffcc99'
            spec_border_color_str = '#ff6c09'
            spec_border_width = 2.

            if numReactions != 0:
                reaction_fill_color = allReactions[0].fill_color
                reaction_fill_color_str = '#%02x%02x%02x' % (
                    reaction_fill_color.r, reaction_fill_color.g,
                    reaction_fill_color.b)
                reaction_line_thickness = allReactions[i].line_thickness

            #add some colors
            color = rInfo.createColorDefinition()
            color.setId("black")
            color.setColorValue("#000000")

            color = rInfo.createColorDefinition()
            color.setId("comp_fill_color")
            color.setColorValue(fill_color_str)

            color = rInfo.createColorDefinition()
            color.setId("comp_border_color")
            color.setColorValue(border_color_str)

            color = rInfo.createColorDefinition()
            color.setId("spec_fill_color")
            color.setColorValue(spec_fill_color_str)

            color = rInfo.createColorDefinition()
            color.setId("spec_border_color")
            color.setColorValue(spec_border_color_str)

            if numReactions != 0:
                color = rInfo.createColorDefinition()
                color.setId("reaction_fill_color")
                color.setColorValue(reaction_fill_color_str)

            # add a list of styles
            style = rInfo.createStyle("compStyle")
            style.getGroup().setFillColor("comp_fill_color")
            style.getGroup().setStroke("comp_border_color")
            style.getGroup().setStrokeWidth(comp_border_width)
            style.addType("COMPARTMENTGLYPH")
            rectangle = style.getGroup().createRectangle()
            rectangle.setCoordinatesAndSize(RelAbsVector(0, 0),
                                            RelAbsVector(0, 0),
                                            RelAbsVector(0, 0),
                                            RelAbsVector(0, 100),
                                            RelAbsVector(0, 100))

            style = rInfo.createStyle("specStyle")
            style.getGroup().setFillColor("spec_fill_color")
            style.getGroup().setStroke("spec_border_color")
            style.getGroup().setStrokeWidth(spec_border_width)
            style.addType("SPECIESGLYPH")
            rectangle = style.getGroup().createRectangle()
            rectangle.setCoordinatesAndSize(RelAbsVector(0, 0),
                                            RelAbsVector(0, 0),
                                            RelAbsVector(0, 0),
                                            RelAbsVector(0, 100),
                                            RelAbsVector(0, 100))

            style = rInfo.createStyle("textStyle")
            style.getGroup().setStroke("black")
            style.getGroup().setStrokeWidth(1.)
            style.addType("TEXTGLYPH")

            if numReactions != 0:
                style = rInfo.createStyle("reactionStyle")
                style.getGroup().setStroke("reaction_fill_color")
                style.getGroup().setStrokeWidth(reaction_line_thickness)
                style.addType("REACTIONGLYPH SPECIESREFERENCEGLYPH")

            sbmlStr_layout_render = writeSBMLToString(doc)
            self.SBMLText.SetValue(sbmlStr_layout_render)

    def Save(self, evt):
        """
        Handler for the "Save" button.
        Save the SBML string to a file.
        """
        self.dirname = ""  #set directory name to blank
        dlg = wx.FileDialog(self.window,
                            "Save As",
                            self.dirname,
                            wildcard="SBML files (*.xml)|*.xml",
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            # Grab the content to be saved
            itcontains = self.SBMLText.GetValue()
            # Open the file for write, write, close
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            filehandle = open(os.path.join(self.dirname, self.filename), 'w')
            filehandle.write(itcontains)
            filehandle.close()
        # Get rid of the dialog to keep things tidy
        dlg.Destroy()
コード例 #11
0
The color of all selected nodes and reactions are set to the picked color.

Version 0.01: Author: Gary Geng (2020)

"""

# pylint: disable=maybe-no-member
import wx
from typing import List
from rkplugin.plugins import CommandPlugin, PluginMetadata, WindowedPlugin
from rkplugin import api

metadata = PluginMetadata(
    name='ColorSelected',
    author='Gary Geng',
    version='0.0.1',
    short_desc='Pick a color, and set everything selected to that color.',
    long_desc=
    'The color of all selected nodes and reactions are set to the picked color.'
)


class ColorSelected(WindowedPlugin):
    def __init__(self):
        """
        Initialize the ColorSelected with no values for a Windowed Plugin.

        Args:
            self

        """
        super().__init__(metadata)
コード例 #12
0
The fill and border color of all nodes are set to a random color.

Version 0.01: Author: Gary Geng (2020)

"""

# pylint: disable=maybe-no-member
import wx
import random
from rkplugin.plugins import CommandPlugin, PluginMetadata
from rkplugin import api

metadata = PluginMetadata(
    name='Disco',
    author='Gary Geng',
    version='0.0.1',
    short_desc='Set all nodes to a random color.',
    long_desc=
    'The fill and border color of all nodes are set to a random color.')


class Disco(CommandPlugin):
    def __init__(self):
        """
        Initialize the ColorSelected with no values for a Command Plugin.

        Args:
            self

        """
        super().__init__(metadata)