Skip to content

Commit d845fec

Browse files
hraniHarshaRani
andauthored
writeSBML: channel's annotation is cleaned up and channel's are written in MMenz form,readSBML:Enzyme-cplx connection of reactant/product's are done based on stoichiometry number and reading back channel from MMenz, connected input pool with msg as 'in' and output pool msg as 'out' (#400)
Co-authored-by: HarshaRani <hrani@ncbs.res.in>
1 parent 868fce7 commit d845fec

File tree

2 files changed

+107
-46
lines changed

2 files changed

+107
-46
lines changed

python/moose/SBML/readSBML.py

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
** copyright (C) 2003-2017 Upinder S. Bhalla. and NCBS
1414
Created : Thu May 13 10:19:00 2016(+0530)
1515
Version
16-
Last-Updated: Mon Jun 16 10:30:00 2019(+0530)
16+
Last-Updated: Fri Mar 20 1:30:00 2020(+0530)
1717
By:HarshaRani
1818
**********************************************************************/
19+
2010:
20+
Mar 04: - Enzyme-cplx reactant/product's based on stoichiometry number of connection are made.
21+
Jan 09: - reading channel back from MMenz
1922
2019:
2023
Jun 06: - both compartment name and Id is mapped to the values in comptSbmlidMooseIdMap
2124
May 23: - checking for integer in Assignment expr
@@ -78,7 +81,6 @@
7881
import moose
7982
from moose.chemUtil.chemConnectUtil import *
8083
from moose.SBML.validation import validateModel
81-
import moose.print_utils as pu
8284
import re
8385
import os
8486

@@ -101,7 +103,7 @@ def mooseReadSBML(filepath, loadpath, solver="ee",validate="on"):
101103
return moose.element('/')
102104

103105
if not os.path.isfile(filepath):
104-
pu.warn('%s is not found ' % filepath)
106+
print('%s is not found ' % filepath)
105107
return moose.element('/')
106108

107109
with open(filepath, "r") as filep:
@@ -119,11 +121,11 @@ def mooseReadSBML(filepath, loadpath, solver="ee",validate="on"):
119121
if tobecontinue:
120122
level = document.getLevel()
121123
version = document.getVersion()
122-
pu.info("File: " + filepath + " (Level " +
124+
print("\nFile: " + filepath + " (Level " +
123125
str(level) + ", version " + str(version) + ")")
124126
model = document.getModel()
125127
if model is None:
126-
pu.error("No model present.")
128+
print("No model present.")
127129
return moose.element('/')
128130
else:
129131

@@ -289,8 +291,7 @@ def checkGroup(basePath,model,comptSbmlidMooseIdMap):
289291
groupInfo[p.getId()] = {"mpath":moosegrp, "splist":memlists}
290292
return groupInfo
291293

292-
def setupEnzymaticReaction(enz, groupName, enzName,
293-
specInfoMap, modelAnnotaInfo,deletcplxMol):
294+
def setupEnzymaticReaction(enz, groupName, enzName, specInfoMap, modelAnnotaInfo,deletcplxMol):
294295
enzPool = (modelAnnotaInfo[groupName]["enzyme"])
295296
enzPool = str(idBeginWith(enzPool))
296297
enzParent = specInfoMap[enzPool]["Mpath"]
@@ -306,17 +307,42 @@ def setupEnzymaticReaction(enz, groupName, enzName,
306307
prdlist = (modelAnnotaInfo[groupName]["product"])
307308
deletcplxMol.append(complx.path)
308309
complx = complx1
310+
311+
enz_sublist = {}
312+
enz_prdlist = {}
313+
#getting the reference of enz_complex_formation to get substrate and its stoichiometry
314+
enz_cplx_form = (modelAnnotaInfo[groupName]["enz_id_s1"])
315+
for tr in range(0,enz_cplx_form.getNumReactants()):
316+
sp = enz_cplx_form.getReactant(tr)
317+
spspieces = sp.getSpecies()
318+
enz_sublist[spspieces] = int(sp.getStoichiometry())
319+
320+
for tr in range(0,enz.getNumProducts()):
321+
sp = enz.getProduct(tr)
322+
spspieces = sp.getSpecies()
323+
enz_prdlist[spspieces] = int(sp.getStoichiometry())
324+
309325
for si in range(0, len(sublist)):
310326
sl = sublist[si]
311327
sl = str(idBeginWith(sl))
312328
mSId = specInfoMap[sl]["Mpath"]
313-
moose.connect(enzyme_, "sub", mSId, "reac")
329+
substoic = 1
330+
if sl in enz_sublist:
331+
substoic = enz_sublist[sl]
332+
333+
for sls in range(0,substoic):
334+
moose.connect(enzyme_, "sub", mSId, "reac")
335+
314336

315337
for pi in range(0, len(prdlist)):
316338
pl = prdlist[pi]
317339
pl = str(idBeginWith(pl))
318340
mPId = specInfoMap[pl]["Mpath"]
319-
moose.connect(enzyme_, "prd", mPId, "reac")
341+
prdstoic = 1
342+
if pl in enz_prdlist:
343+
prdstoic = enz_prdlist[pl]
344+
for pls in range(0,prdstoic):
345+
moose.connect(enzyme_, "prd", mPId, "reac")
320346

321347
if (enz.isSetNotes):
322348
pullnotes(enz, enzyme_)
@@ -335,16 +361,16 @@ def addSubPrd(reac, reName, type, reactSBMLIdMooseId, specInfoMap):
335361
rctMapIter[sp] = rct.getStoichiometry()
336362
else:
337363
rctMapIter[sp] = 1
338-
if rct.getStoichiometry() > 1:
339-
pass
340-
# print " stoich ",reac.name,rct.getStoichiometry()
341364
noplusStoichsub = noplusStoichsub + rct.getStoichiometry()
342365
for key, value in list(rctMapIter.items()):
343366
key = str(idBeginWith(key))
344367
src = specInfoMap[key]["Mpath"]
345368
des = reactSBMLIdMooseId[reName]["MooseId"]
346369
for s in range(0, int(value)):
347-
moose.connect(des, 'sub', src, 'reac', 'OneToOne')
370+
if (reactSBMLIdMooseId[reName]["MooseId"]).className == "ConcChan":
371+
moose.connect(des, 'in', src, 'reac', 'OneToOne')
372+
else:
373+
moose.connect(des, 'sub', src, 'reac', 'OneToOne')
348374
addSubinfo = {"nSub": noplusStoichsub}
349375
reactSBMLIdMooseId[reName].update(addSubinfo)
350376

@@ -359,9 +385,6 @@ def addSubPrd(reac, reName, type, reactSBMLIdMooseId, specInfoMap):
359385
else:
360386
rctMapIter[sp] = 1
361387

362-
if rct.getStoichiometry() > 1:
363-
pass
364-
# print " stoich prd",reac.name,rct.getStoichiometry()
365388
noplusStoichprd = noplusStoichprd + rct.getStoichiometry()
366389

367390
for key, values in list(rctMapIter.items()):
@@ -370,7 +393,10 @@ def addSubPrd(reac, reName, type, reactSBMLIdMooseId, specInfoMap):
370393
key = parentSp = str(idBeginWith(key))
371394
des = specInfoMap[key]["Mpath"]
372395
for i in range(0, int(values)):
373-
moose.connect(src, 'prd', des, 'reac', 'OneToOne')
396+
if (reactSBMLIdMooseId[reName]["MooseId"]).className == "ConcChan":
397+
moose.connect(src, 'out', des, 'reac', 'OneToOne')
398+
else:
399+
moose.connect(src, 'prd', des, 'reac', 'OneToOne')
374400
addPrdinfo = {"nPrd": noplusStoichprd}
375401
reactSBMLIdMooseId[reName].update(addPrdinfo)
376402

@@ -504,6 +530,10 @@ def getObjAnnotation(obj, modelAnnotationInfo):
504530
annotateMap[nodeName] = nodeValue
505531
if nodeName == "motorConstant":
506532
annotateMap[nodeName] = nodeValue
533+
if nodeName == "Channel":
534+
annotateMap[nodeName] = nodeValue
535+
if nodeName == "Permeability":
536+
annotateMap[nodeName] = nodeValue
507537
return annotateMap
508538

509539

@@ -575,7 +605,8 @@ def getEnzAnnotation(obj, modelAnnotaInfo, rev,
575605
"stage": list(annotateMap["stage"])[0],
576606
"substrate": sublist,
577607
"k1": k1,
578-
"k2": k2
608+
"k2": k2,
609+
"enz_id_s1":obj
579610
}
580611
)
581612
else:
@@ -584,7 +615,8 @@ def getEnzAnnotation(obj, modelAnnotaInfo, rev,
584615
"stage": list(annotateMap["stage"])[0],
585616
"substrate": sublist,
586617
"k1": k1,
587-
"k2": k2
618+
"k2": k2,
619+
"enz_id_s1":obj
588620
#"group" : list(annotateMap["Group"])[0],
589621
#"xCord" : list(annotateMap["xCord"])[0],
590622
#"yCord" : list(annotateMap["yCord"]) [0]
@@ -628,6 +660,7 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
628660

629661
for ritem in range(0, model.getNumReactions()):
630662
reactionCreated = False
663+
channelCreated = False
631664
groupName = ""
632665
rName = ""
633666
rId = ""
@@ -637,7 +670,6 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
637670
reacAnnoInfo = getObjAnnotation(reac, modelAnnotaInfo)
638671
# if "Group" in reacAnnoInfo:
639672
# group = reacAnnoInfo["Group"]
640-
641673
if (reac.isSetId()):
642674
rId = reac.getId()
643675
#groups = [k for k, v in groupInfo.items() if rId in v]
@@ -662,7 +694,6 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
662694
if (reac.getAnnotation() is not None):
663695
groupName = getEnzAnnotation(
664696
reac, modelAnnotaInfo, rev, globparameterIdValue, specInfoMap,funcDef)
665-
666697
if (groupName != "" and list(
667698
modelAnnotaInfo[groupName]["stage"])[0] == 3):
668699
reaction_, reactionCreated = setupEnzymaticReaction(
@@ -693,7 +724,10 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
693724
reacInfo.textColor = v
694725

695726
elif(groupName == ""):
696-
727+
channelfound = False
728+
for k, v in list(reacAnnoInfo.items()):
729+
if k == "Channel":
730+
channelfound = True
697731
numRcts = reac.getNumReactants()
698732
numPdts = reac.getNumProducts()
699733
nummodifiers = reac.getNumModifiers()
@@ -702,11 +736,17 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
702736
# reactionCreated = False
703737

704738
if not (numRcts and numPdts):
705-
print("Warning: %s" %(rName)," : Substrate or Product is missing, we will be skiping creating this reaction in MOOSE")
739+
#print("Warning: %s" %(rName)," : Substrate or Product is missing, we will be skiping creating this reaction in MOOSE")
740+
print("Warning: %s" %(rName)," : Substrate or Product is missing, we will be skiping creating this %s" %("reaction" if not channelfound else "Channel") +" in MOOSE")
706741
reactionCreated = False
707742
elif (reac.getNumModifiers() > 0):
708-
reactionCreated, reaction_ = setupMMEnzymeReaction(
709-
reac, rName, specInfoMap, reactSBMLIdMooseId, modelAnnotaInfo, model, globparameterIdValue)
743+
if not channelfound:
744+
reactionCreated, reaction_ = setupMMEnzymeReaction(
745+
reac, rName, specInfoMap, reactSBMLIdMooseId, modelAnnotaInfo, model, globparameterIdValue)
746+
else:
747+
channelCreated, channel_ = setupConcChannel(reac,rName,specInfoMap,reactSBMLIdMooseId, modelAnnotaInfo, model, globparameterIdValue)
748+
reactSBMLIdMooseId[rName] = {
749+
"MooseId": channel_}
710750
# elif (reac.getNumModifiers() > 0):
711751
# reactionCreated = setupMMEnzymeReaction(reac,rName,specInfoMap,reactSBMLIdMooseId,modelAnnotaInfo,model,globparameterIdValue)
712752
# reaction_ = reactSBMLIdMooseId['classical']['MooseId']
@@ -731,7 +771,7 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
731771
reaction_ = moose.Reac(speCompt + '/' + rName)
732772
reactionCreated = True
733773
reactSBMLIdMooseId[rName] = {
734-
"MooseId": reaction_, "className ": "reaction"}
774+
"MooseId": reaction_}
735775
elif (numPdts):
736776
# In moose, reactions compartment are decided from first Substrate compartment info
737777
# substrate is missing then check for product
@@ -743,8 +783,11 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
743783
reaction_ = moose.Reac(speCompt + '/' + rName)
744784
reactionCreated = True
745785
reactSBMLIdMooseId[rId] = {
746-
"MooseId": reaction_, "className": "reaction"}
747-
if reactionCreated:
786+
"MooseId": reaction_}
787+
if reactionCreated or channelCreated:
788+
if channelCreated:
789+
reaction_ = channel_
790+
748791
if (reac.isSetNotes):
749792
pullnotes(reac, reaction_)
750793
reacAnnoInfo = {}
@@ -787,6 +830,8 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue,fun
787830
elif reaction_.className == "MMenz":
788831
reaction_.kcat = kfvalue
789832
reaction_.Km = kbvalue
833+
elif reaction_.className == "ConcChan":
834+
reaction_.permeability = kfvalue
790835
for l in deletecplxMol:
791836
if moose.exists(l):
792837
moose.delete(moose.element(l))
@@ -1449,6 +1494,23 @@ def createCompartment(basePath, model, comptSbmlidMooseIdMap):
14491494
return False," EndoMesh's surrounding compartment missing or wrong deleting the compartment check the file"
14501495
return True,""
14511496

1497+
def setupConcChannel(reac, rName, specInfoMap, reactSBMLIdMooseId,
1498+
modelAnnotaInfo, model, globparameterIdValue):
1499+
msg = ""
1500+
errorFlag = ""
1501+
numRcts = reac.getNumReactants()
1502+
numPdts = reac.getNumProducts()
1503+
nummodifiers = reac.getNumModifiers()
1504+
if (nummodifiers):
1505+
parent = reac.getModifier(0)
1506+
parentSp = parent.getSpecies()
1507+
parentSp = str(idBeginWith(parentSp))
1508+
enzParent = specInfoMap[parentSp]["Mpath"]
1509+
ConcChan = moose.ConcChan(enzParent.path + '/' + rName)
1510+
moose.connect(enzParent, "nOut", ConcChan, "setNumChan")
1511+
channelCreated = True
1512+
if channelCreated:
1513+
return (channelCreated,ConcChan)
14521514

14531515
def setupMMEnzymeReaction(reac, rName, specInfoMap, reactSBMLIdMooseId,
14541516
modelAnnotaInfo, model, globparameterIdValue):
@@ -1465,7 +1527,7 @@ def setupMMEnzymeReaction(reac, rName, specInfoMap, reactSBMLIdMooseId,
14651527
MMEnz = moose.MMenz(enzParent.path + '/' + rName)
14661528
moose.connect(enzParent, "nOut", MMEnz, "enzDest")
14671529
reactionCreated = True
1468-
reactSBMLIdMooseId[rName] = {"MooseId": MMEnz, "className": "MMEnz"}
1530+
reactSBMLIdMooseId[rName] = {"MooseId": MMEnz}
14691531
if reactionCreated:
14701532
if (reac.isSetNotes):
14711533
pullnotes(reac, MMEnz)

python/moose/SBML/writeSBML.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
** copyright (C) 2003-2017 Upinder S. Bhalla. and NCBS
1414
Created : Friday May 27 12:19:00 2016(+0530)
1515
Version
16-
Last-Updated: Wed 8 Jan 14:15:10 2020(+0530)
16+
Last-Updated: Fri 20 Mar 13:15:10 2020(+0530)
1717
By: HarshaRani
1818
**********************************************************************/
1919
/****************************
2020
2020
21+
Mar 20: Channel Annotation is cleaned up
2122
Jan 08: added function to write Concchannel in form of MMenz
2223
Km in the kinetic law for MMenz is written to the power based on the number of substrate
2324
2019
@@ -259,31 +260,33 @@ def writeChannel(modelpath, cremodel_, sceneitems,groupInfo):
259260
compt = ""
260261
notesE = ""
261262
groupName = moose.element("/")
262-
263+
if not moose.exists(chan.path+'/info'):
264+
moose.Annotator(chan.path+'/info')
263265
if moose.exists(chan.path + '/info'):
264266
Anno = moose.Annotator(chan.path + '/info')
265267
notesE = Anno.notes
266268
element = moose.element(chan)
267269
ele = getGroupinfo(element)
268270
ele = findGroup_compt(element)
269271
chanAnno = " "
270-
if ele.className == "Neutral" or sceneitems or Anno.x or Anno.y:
271-
chanannoexist = True
272+
#if ele.className == "Neutral" or sceneitems or Anno.x or Anno.y:
273+
# chanannoexist = True
274+
chanannoexist = True
272275
if chanannoexist:
273276
chanAnno = "<moose:ModelAnnotation>\n"
274277
if ele.className == "Neutral":
275278
groupName = ele
276279
if sceneitems:
277280
#Saved from GUI, then scene co-ordinates are passed
278-
chanGpnCorCol = chanGpnCorCol + "<moose:xCord>" + \
281+
chanGpnCorCol = "<moose:xCord>" + \
279282
str(sceneitems[chan]['x']) + "</moose:xCord>\n" + \
280283
"<moose:yCord>" + \
281284
str(sceneitems[chan]['y'])+ "</moose:yCord>\n"
282285
else:
283286
#Saved from cmdline,genesis coordinates are kept as its
284287
# SBML, cspace, python, then auto-coordinates are done
285288
#and coordinates are updated in moose Annotation field
286-
chanGpnCorCol = chanGpnCorCol + "<moose:xCord>" + \
289+
chanGpnCorCol = "<moose:xCord>" + \
287290
str(Anno.x) + "</moose:xCord>\n" + \
288291
"<moose:yCord>" + \
289292
str(Anno.y)+ "</moose:yCord>\n"
@@ -313,7 +316,6 @@ def writeChannel(modelpath, cremodel_, sceneitems,groupInfo):
313316
str(chan.getDataIndex()) +
314317
"_"))
315318
channel.setId(chansetId)
316-
317319
if groupName != moose.element('/'):
318320
if groupName not in groupInfo:
319321
groupInfo[groupName]=[chansetId]
@@ -322,12 +324,11 @@ def writeChannel(modelpath, cremodel_, sceneitems,groupInfo):
322324

323325
channel.setName(str(idBeginWith(convertSpecialCharshot(chan.name))))
324326
channel.setReversible(True)
325-
channel.setFast(False)
326-
if chanannoexist:
327-
canAnno = chanAnno + chanGpnCorCol
328-
chanAnno = "<moose:ConcChannel>\n" + \
329-
chanGpnCorCol + "</moose:ConcChannel>"
330-
channel.setAnnotation(chanAnno)
327+
channel.setFast(False)
328+
chanAnno = "<moose:ModelAnnotation>\n <moose:Channel>ConcChannel</moose:Channel>\n" + \
329+
chanGpnCorCol + "</moose:ModelAnnotation>"
330+
channel.setAnnotation(chanAnno)
331+
331332
noofSub, sRateLawS = getSubprd(cremodel_, False, "sub", chanSub)
332333
# Modifier
333334
chanMod = chan.neighbors["setNumChan"]
@@ -1118,10 +1119,8 @@ def writeSpecies(modelpath, cremodel_, sbmlDoc, sceneitems,speGroup):
11181119
if not moose.exists(spe.path+'/info'):
11191120
cplxinfo = moose.Annotator(spe.path+'/info')
11201121
enzpath = moose.element(spe.parent.path+'/info')
1121-
1122-
cplxinfo.x = moose.element(moose.element(spe.parent.path+'/info').x)
1123-
1124-
cplxinfo.y = int((moose.element(spe.parent.path+'/info').y))+10
1122+
cplxinfo.x = moose.element(enzpath).x
1123+
cplxinfo.y = int((moose.element(enzpath).y))+10
11251124

11261125
if (moose.element(enz.parent), moose.PoolBase):
11271126
# print " found a cplx name ",spe.parent,

0 commit comments

Comments
 (0)