def test_add_basic(self): """Simple tests for reactions.""" api.add_reaction(self.neti, 'AB', [0], [1]) reactions = api.get_reactions(self.neti) self.assertEqual(1, len(reactions)) self.assertEqual(1, len(reactions[0].sources)) self.assertEqual(1, len(reactions[0].targets)) self.assertEqual(0, reactions[0].sources[0]) self.assertEqual(1, reactions[0].targets[0])
def test_reverse(self): api.add_reaction(self.neti, 'AB', [0], [1]) self.assertTrue(api.is_reactant(self.neti, 0, 0)) self.assertFalse(api.is_reactant(self.neti, 1, 0)) self.assertFalse(api.is_product(self.neti, 0, 0)) self.assertTrue(api.is_product(self.neti, 1, 0)) self.assertFalse(api.is_reactant(self.neti, 2, 0)) self.assertFalse(api.is_product(self.neti, 2, 0)) api.add_reaction(self.neti, 'AC', [0], [2]) self.assertEqual(api.get_reactions_as_reactant(self.neti, 0), {0, 1}) self.assertEqual(api.get_reactions_as_product(self.neti, 0), set()) self.assertEqual(api.get_reactions_as_product(self.neti, 2), {1})
def test_delete_items(self): api.add_reaction(self.neti, 'AB', [0], [1]) with self.assertRaises(NodeNotFreeError): api.delete_node(self.neti, 0) with self.assertRaises(NodeNotFreeError): api.delete_node(self.neti, 1) api.delete_reaction(self.neti, 0) api.delete_node(self.neti, 0) api.delete_node(self.neti, 1) api.delete_node(self.neti, 2) self.assertEqual(list(), api.get_reactions(self.neti)) self.assertEqual(list(), api.get_nodes(self.neti))
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 test_simple_handles(self): """Simple tests for Bezier handles.""" api.add_reaction(self.neti, 'AB', [0], [1]) api.set_reaction_center_handle(0, 0, Vec2(-10, 30)) self.assertEqual(api.get_reaction_center_handle(0, 0), Vec2(-10, 30)) api.set_reaction_node_handle(0, 0, 0, True, Vec2(40, 50)) self.assertEqual(api.get_reaction_node_handle(0, 0, 0, True), Vec2(40, 50)) with self.assertRaises(NodeIndexError): api.get_reaction_node_handle(0, 0, 12, True) # test for the case where node exists but not reactant/product with self.assertRaises(ValueError): api.get_reaction_node_handle(0, 0, 1, True) with self.assertRaises(ValueError): api.get_reaction_node_handle(0, 0, 0, False) with self.assertRaises(ReactionIndexError): api.get_reaction_node_handle(0, 2, 0, True)
def test_exceptional_reactions(self): with self.assertRaises(ValueError): api.add_reaction(self.neti, 'circular', [2], [2]) with self.assertRaises(ValueError): api.add_reaction(self.neti, 'empty_reactants', [], [2]) with self.assertRaises(ValueError): api.add_reaction(self.neti, 'empty_products', [2], [])
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)
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])