# -*- coding: utf-8 -*-
""" Chemical Signalling model loaded into moose can be save into Genesis-Kkit format """
__author__ = "Harsha Rani"
__copyright__ = "Copyright 2017, Harsha Rani and NCBS Bangalore"
__credits__ = ["NCBS Bangalore"]
__license__ = "GNU GPL"
__version__ = "1.0.0"
__maintainer__ = "Harsha Rani"
__email__ = "hrani@ncbs.res.in"
__status__ = "Development"
__updated__ = "Dec 08 2018"
# 2018
# Dec 08: using restoreXreacs from fixXreacs
# Nov 22: searched for _xfer_ instead of xfer
# Nov 21: xfer pool are not written and cleaned up if part of Reaction/Enzyme or notes,
# group are checked under all the mesh
# Oct 16: Channels are written back to genesis
# only zeroth element is taken for written back to genesis, this is true for CubeMesh and CylMesh
# 2017
# Aug 8 : All the moose object which doesn't have compartment are not written. Error message are appended
import sys
import random
import re
import moose
from moose.chemUtil.chemConnectUtil import *
from moose.chemUtil.graphUtils import *
from moose.fixXreacs import restoreXreacs
foundmatplotlib_ = False
try:
import matplotlib
foundmatplotlib_ = True
except Exception as e:
pass
GENESIS_COLOR_SEQUENCE = ((248, 0, 255), (240, 0, 255), (232, 0, 255), (224, 0, 255), (216, 0, 255), (208, 0, 255),
(200, 0, 255), (192, 0, 255), (184, 0, 255), (176, 0, 255), (168, 0, 255), (160, 0, 255), (152, 0, 255), (144, 0, 255),
(136, 0, 255), (128, 0, 255), (120, 0, 255), (112, 0, 255), (104, 0, 255), (96, 0, 255), (88, 0, 255), (80, 0, 255),
(72, 0, 255), (64, 0, 255), (56, 0, 255), (48, 0, 255), (40, 0, 255), (32, 0, 255), (24, 0, 255), (16, 0, 255),
(8, 0, 255), (0, 0, 255), (0, 8, 248), (0, 16, 240), (0, 24, 232), (0, 32, 224), (0, 40, 216), (0, 48, 208),
(0, 56, 200), (0, 64, 192), (0, 72, 184), (0, 80, 176), (0, 88, 168), (0, 96, 160), (0, 104, 152), (0, 112, 144),
(0, 120, 136), (0, 128, 128), (0, 136, 120), (0, 144, 112), (0, 152, 104), (0, 160, 96), (0, 168, 88), (0, 176, 80),
(0, 184, 72), (0, 192, 64), (0, 200, 56), (0, 208, 48), (0, 216, 40), (0, 224, 32), (0, 232, 24), (0, 240, 16), (0, 248, 8),
(0, 255, 0), (8, 255, 0), (16, 255, 0), (24, 255, 0), (32, 255, 0), (40, 255, 0), (48, 255, 0), (56, 255, 0), (64, 255, 0),
(72, 255, 0), (80, 255, 0), (88, 255, 0), (96, 255, 0), (104, 255, 0), (112, 255, 0), (120, 255, 0), (128, 255, 0),
(136, 255, 0), (144, 255, 0), (152, 255, 0), (160, 255, 0), (168, 255, 0), (176, 255, 0), (184, 255, 0), (192, 255, 0),
(200, 255, 0), (208, 255, 0), (216, 255, 0), (224, 255, 0), (232, 255, 0), (240, 255, 0), (248, 255, 0), (255, 255, 0),
(255, 248, 0), (255, 240, 0), (255, 232, 0), (255, 224, 0), (255, 216, 0), (255, 208, 0), (255, 200, 0), (255, 192, 0),
(255, 184, 0), (255, 176, 0), (255, 168, 0), (255, 160, 0), (255, 152, 0), (255, 144, 0), (255, 136, 0), (255, 128, 0),
(255, 120, 0), (255, 112, 0), (255, 104, 0), (255, 96, 0), (255, 88, 0), (255, 80, 0), (255, 72, 0), (255, 64, 0),
(255, 56, 0), (255, 48, 0), (255, 40, 0), (255, 32, 0), (255, 24, 0), (255, 16, 0), (255, 8, 0), (255, 0, 0))
#Todo : To be written
# --StimulusTable
def mooseWriteKkit( modelpath, filename, sceneitems={}):
global foundmatplotlib_
if not foundmatplotlib_:
print('No maplotlib found.'
'\nThis module can be installed by following command in terminal:'
'\n\t sudo apt install python-maplotlib', "")
return False
else:
error = ""
if filename.rfind('.') != -1:
filename = filename[:filename.rfind('.')]
else:
filename = filename[:len(filename)]
filename = filename+'.g'
global NA
NA = 6.0221415e23
global cmin,cmax,xmin,xmax,ymin,ymax
cmin, xmin, ymin = 0, 0, 0
cmax, xmax, ymax = 1, 1, 1
moose.fixXreacs.restoreXreacs(modelpath)
compt = moose.wildcardFind(modelpath+'/##[0][ISA=ChemCompt]')
maxVol = estimateDefaultVol(compt)
positionInfoExist = True
if compt:
if bool(sceneitems):
cmin,cmax,xmin1,xmax1,ymin1,ymax1 = findMinMax(sceneitems)
elif not bool(sceneitems):
srcdesConnection = {}
setupItem(modelpath,srcdesConnection)
meshEntry,xmin,xmax,ymin,ymax,positionInfoExist,sceneitems = setupMeshObj(modelpath)
if not positionInfoExist:
#cmin,cmax,sceneitems = autoCoordinates(meshEntry,srcdesConnection)
sceneitems = autoCoordinates(meshEntry,srcdesConnection)
if not positionInfoExist:
# if position are not from kkit, then zoom factor is applied while
# writing to genesis. Like if position is from pyqtSceneItem or auto-coordinates
cmin,cmax,xmin1,xmax1,ymin1,ymax1 = findMinMax(sceneitems)
for k,v in list(sceneitems.items()):
anno = moose.element(k.path+'/info')
#x1 = calPrime(v['x'])
#y1 = calPrime(v['y'])
#sceneitems[k]['x'] = x1
#sceneitems[k]['y'] = y1
f = open(filename, 'w')
writeHeader (f,maxVol)
gtId_vol = writeCompartment(modelpath,compt,f)
errors = ""
error = writePool(modelpath,f,gtId_vol,sceneitems)
errors = errors+error
reacList,error= writeReac(modelpath,f,sceneitems)
errors = errors+error
enzList,error = writeEnz(modelpath,f,sceneitems)
errors = errors+error
chanList, error = writeConcChan(modelpath,f,sceneitems)
errors = errors+error
error = writeStimulus(modelpath,f)
errors = errors+error
error = writeSumtotal(modelpath,f)
errors = errors+error
#writeSumtotal(modelpath,f)
f.write("simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n"
"simundump xgraph /graphs/conc2 0 0 100 0 1 0\n")
tgraphs = moose.wildcardFind(modelpath+'/##[0][ISA=Table2]')
first, second = " ", " "
if tgraphs:
first,second = writeplot(tgraphs,f)
if first:
f.write(first)
f.write("simundump xgraph /moregraphs/conc3 0 0 100 0 1 0\n"
"simundump xgraph /moregraphs/conc4 0 0 100 0 1 0\n")
if second:
f.write(second)
f.write("simundump xcoredraw /edit/draw 0 -6 4 -2 6\n"
"simundump xtree /edit/draw/tree 0 \\\n"
" /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \"edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>\" auto 0.6\n"
"simundump xtext /file/notes 0 1\n")
storeReacMsg(reacList,f)
storeEnzMsg(enzList,f)
storeChanMsg(chanList,f)
if tgraphs:
storePlotMsgs(tgraphs,f)
writeFooter1(f)
writeNotes(modelpath,f)
writeFooter2(f)
print('Written to file '+filename)
return errors, True
else:
print("Warning: writeKkit:: No model found on " , modelpath)
return False
def findMinMax(sceneitems):
cmin = 0.0
cmax = 1.0
xmin,xymin = 0.0,0.0
xmax,xymax = 1.0,1.0
xycord = []
xcord = []
ycord = []
for k,v in list(sceneitems.items()):
xycord.append(v['x'])
xycord.append(v['y'])
xcord.append(v['x'])
ycord.append(v['y'])
xmin = min(xcord)
xmax = max(xcord)
ymin = min(ycord)
ymax = max(ycord)
cmin = min(xycord)
cmax = max(xycord)
return cmin,cmax,xmin,xmax,ymin,ymax
def calPrime(x):
prime = int((20*(float(x-cmin)/float(cmax-cmin)))-10)
return prime
def storeCplxEnzMsgs( enz, f ):
for sub in enz.neighbors["subOut"]:
s = "addmsg /kinetics/" + trimPath( moose.element(sub) ) + " /kinetics/" + trimPath(enz) + " SUBSTRATE n \n";
s = s+ "addmsg /kinetics/" + trimPath( enz ) + " /kinetics/" + trimPath( sub ) + " REAC sA B \n";
f.write(s)
for prd in enz.neighbors["prd"]:
s = "addmsg /kinetics/" + trimPath( enz ) + " /kinetics/" + trimPath(prd) + " MM_PRD pA\n";
f.write( s )
for enzOut in enz.neighbors["enzOut"]:
s = "addmsg /kinetics/" + trimPath( enzOut ) + " /kinetics/" + trimPath(enz) + " ENZYME n\n";
s = s+ "addmsg /kinetics/" + trimPath( enz ) + " /kinetics/" + trimPath(enzOut) + " REAC eA B\n";
f.write( s )
def storeMMenzMsgs( enz, f):
subList = enz.neighbors["subOut"]
prdList = enz.neighbors["prd"]
enzDestList = enz.neighbors["enzDest"]
for esub in subList:
es = "addmsg /kinetics/" + trimPath(moose.element(esub)) + " /kinetics/" + trimPath(enz) + " SUBSTRATE n \n";
es = es+"addmsg /kinetics/" + trimPath(enz) + " /kinetics/" + trimPath(moose.element(esub)) + " REAC sA B \n";
f.write(es)
for eprd in prdList:
es = "addmsg /kinetics/" + trimPath( enz ) + " /kinetics/" + trimPath( moose.element(eprd)) + " MM_PRD pA \n";
f.write(es)
for eenzDest in enzDestList:
enzDest = "addmsg /kinetics/" + trimPath( moose.element(eenzDest)) + " /kinetics/" + trimPath( enz ) + " ENZYME n \n";
f.write(enzDest)
def storeEnzMsg( enzList, f):
for enz in enzList:
enzClass = enz.className
if (enzClass == "ZombieMMenz" or enzClass == "MMenz"):
storeMMenzMsgs(enz, f)
else:
storeCplxEnzMsgs( enz, f )
def storeChanMsg(chanList,f):
for channel in chanList:
for chanOL in channel.neighbors['out']:
eo = "addmsg /kinetics/" + trimPath(moose.element(channel)) + " /kinetics/" + trimPath(moose.element(chanOL))+ " REAC B A \n";
eo = eo +"addmsg /kinetics/" + trimPath(moose.element(chanOL)) + " /kinetics/"+trimPath(moose.element(channel))+" PRODUCT n vol \n";
f.write(eo)
for chanIL in channel.neighbors['in']:
ei = "addmsg /kinetics/" + trimPath(moose.element(channel)) + " /kinetics/" + trimPath(moose.element(chanIL))+ " REAC A B \n";
ei = ei +"addmsg /kinetics/" + trimPath(moose.element(chanIL)) + " /kinetics/"+trimPath(moose.element(channel))+" SUBSTRATE n vol \n";
f.write(ei)
for chanSNC in channel.neighbors['setNumChan']:
cff = "addmsg /kinetics/"+trimPath(moose.element(chanSNC))+ " /kinetics/"+trimPath(moose.element(channel))+ " NUMCHAN n \n"
f.write(cff)
def writeConcChan(modelpath,f,sceneitems):
error = ""
concChanList = moose.wildcardFind(modelpath+'/##[0][ISA=ConcChan]')
for cChan in concChanList:
if findCompartment(cChan) == moose.element('/'):
error = error + " \n "+cChan.path+ " doesn't have compartment ignored to write to genesis"
else:
x = random.randrange(0,10)
y = random.randrange(0,10)
textcolor = ""
color = ""
if len(moose.element(cChan).neighbors['setNumChan']) == 1:
chanParent = moose.element(moose.element(cChan).neighbors['setNumChan'][0])
if not (isinstance(chanParent,moose.PoolBase)):
print(" raise exception Channel doesn't have pool as parent %s",moose.element(cChan).path)
return False,"raise exception Channel doesn't have pool as parent"
else:
vol = chanParent.volume * NA * 1e-3;
cinfo = cChan.path+'/info'
if moose.exists(cinfo):
x = moose.Annotator(cinfo).getField('x')
y = moose.Annotator(cinfo).getField('y')
#x = sceneitems[cChan]['x']
#y = sceneitems[cChan]['y']
color = moose.Annotator(cinfo).getField('color')
color = getColorCheck(color,GENESIS_COLOR_SEQUENCE)
textcolor = moose.Annotator(cinfo).getField('textColor')
textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE)
else:
error = error + "\n x and y co-ordinates are not specified for `" + cChan.name+ "` zero will be assigned \n "
if color == "" or color == " ":
color = getRandomColor()
if textcolor == "" or textcolor == " ":
textcolor = getRandomColor()
f.write("simundump kchan /kinetics/" + trimPath(cChan)+ " " + str(int(1)) + " " + str(cChan.permeability)+ " " +
str(int(0)) + " " +
str(int(0)) + " " +
str(int(0)) + " " +
str(int(0)) + " " +
str("") + " " +
str(textcolor) + " " + str(color) + " \"\"" +
" " + str(int(x)) + " " + str(int(y)) + " "+str(int(0))+"\n")
return concChanList,error
def writeEnz( modelpath,f,sceneitems):
error = ""
enzList = moose.wildcardFind(modelpath+'/##[0][ISA=EnzBase]')
for enz in enzList:
if findCompartment(enz) == moose.element('/'):
error = error + " \n "+enz.path+ " doesn't have compartment ignored to write to genesis"
else:
x = random.randrange(0,10)
y = random.randrange(0,10)
textcolor = ""
color = ""
k1 = 0;
k2 = 0;
k3 = 0;
nInit = 0;
concInit = 0;
n = 0;
conc = 0;
if len(moose.element(enz).neighbors['enzDest']) == 1:
enzParent = moose.element(moose.element(enz).neighbors['enzDest'][0])
if not (isinstance(enzParent,moose.PoolBase)):
print(" raise exception enz doesn't have pool as parent %s",moose.element(enz).path)
return False
else:
vol = enzParent.volume * NA * 1e-3;
isMichaelisMenten = 0;
enzClass = enz.className
if (enzClass == "ZombieMMenz" or enzClass == "MMenz"):
k1 = enz.numKm
k3 = enz.kcat
k2 = 4.0*k3;
k1 = (k2 + k3) / k1;
isMichaelisMenten = 1;
elif (enzClass == "ZombieEnz" or enzClass == "Enz"):
k1 = enz.k1
k2 = enz.k2
k3 = enz.k3
if enz.neighbors['cplx']:
cplx = enz.neighbors['cplx'][0]
nInit = cplx.nInit[0];
else:
cplx = moose.Pool(enz.path+"/cplx")
moose.Annotator(cplx.path+'/info')
moose.connect( enz, 'cplx', cplx, 'reac' )
nInit = cplx.nInit
einfo = enz.path+'/info'
if moose.exists(einfo):
x = sceneitems[enz]['x']
y = sceneitems[enz]['y']
color = moose.Annotator(einfo).getField('color')
color = getColorCheck(color,GENESIS_COLOR_SEQUENCE)
textcolor = moose.Annotator(einfo).getField('textColor')
textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE)
else:
error = error + "\n x and y co-ordinates are not specified for `" + enz.name+ "` zero will be assigned \n "
if color == "" or color == " ":
color = getRandomColor()
if textcolor == "" or textcolor == " ":
textcolor = getRandomColor()
f.write("simundump kenz /kinetics/" + trimPath(enz) + " " + str(int(0))+ " " +
str(concInit) + " " +
str(conc) + " " +
str(nInit) + " " +
str(n) + " " +
str(vol) + " " +
str(k1) + " " +
str(k2) + " " +
str(k3) + " " +
str(0) + " " +
str(isMichaelisMenten) + " " +
"\"\"" + " " +
str(textcolor) + " " + str(color) + " \"\"" +
" " + str(int(x)) + " " + str(int(y)) + " "+str(int(0))+"\n")
return enzList,error
def nearestColorIndex(color, color_sequence):
#Trying to find the index to closest color map from the rainbow pickle file for matching the Genesis color map
distance = [ (color[0] - temp[0]) ** 2 + (color[1] - temp[1]) ** 2 + (color[2] - temp[2]) ** 2
for temp in color_sequence]
minindex = 0
for i in range(1, len(distance)):
if distance[minindex] > distance[i] : minindex = i
return minindex
def storeReacMsg(reacList,f):
for reac in reacList:
reacPath = trimPath( reac);
sublist = reac.neighbors["subOut"]
prdlist = reac.neighbors["prd"]
for sub in sublist:
s = "addmsg /kinetics/" + trimPath( sub ) + " /kinetics/" + reacPath + " SUBSTRATE n \n";
s = s + "addmsg /kinetics/" + reacPath + " /kinetics/" + trimPath( sub ) + " REAC A B \n";
f.write(s)
for prd in prdlist:
s = "addmsg /kinetics/" + trimPath( prd ) + " /kinetics/" + reacPath + " PRODUCT n \n";
s = s + "addmsg /kinetics/" + reacPath + " /kinetics/" + trimPath( prd ) + " REAC B A\n";
f.write( s)
def writeReac(modelpath,f,sceneitems):
error = ""
reacList = moose.wildcardFind(modelpath+'/##[0][ISA=ReacBase]')
for reac in reacList:
if findCompartment(reac) == moose.element('/'):
error = error + " \n "+reac.path+ " doesn't have compartment ignored to write to genesis"
else:
color = ""
textcolor = ""
kf = reac.numKf
kb = reac.numKb
# if sceneitems != None:
# value = sceneitems[reac]
# x = calPrime(value['x'])
# y = calPrime(value['y'])
rinfo = reac.path+'/info'
if moose.exists(rinfo):
x = sceneitems[reac]['x']
y = sceneitems[reac]['y']
color = moose.Annotator(rinfo).getField('color')
color = getColorCheck(color,GENESIS_COLOR_SEQUENCE)
textcolor = moose.Annotator(rinfo).getField('textColor')
textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE)
else:
x = 0
y = 0
error = error + "\n x and y co-ordinates are not specified for `" + reac.name+ "` zero will be assigned \n "
if color == "" or color == " ":
color = getRandomColor()
if textcolor == "" or textcolor == " ":
textcolor = getRandomColor()
f.write("simundump kreac /kinetics/" + trimPath(reac) + " " +str(0) +" "+ str(kf) + " " + str(kb) + " \"\" " +
str(color) + " " + str(textcolor) + " " + str(int(x)) + " " + str(int(y)) + " "+ str(0)+"\n")
return reacList,error
def trimPath(mobj):
original = mobj
mobj = moose.element(mobj)
found = False
while not isinstance(mobj,moose.ChemCompt) and mobj.path != "/":
mobj = moose.element(mobj.parent)
found = True
if mobj.path == "/":
print(original, " object doesn't have compartment as a parent ")
return
#other than the kinetics compartment, all the othername are converted to group in Genesis which are place under /kinetics
# Any moose object comes under /kinetics then one level down the path is taken.
# e.g /group/poolObject or /Reac
if found:
if mobj.name != "kinetics":# and ( (mobj.className != "CubeMesh") and (mobj.className != "CylMesh") and (mobj.className != "EndoMesh") and (mobj.className != "NeuroMesh")):
splitpath = original.path[(original.path.find(mobj.name)):len(original.path)]
else:
pos = original.path.find(mobj.name)
#ss = re.compile(r'\b%s\b' %mobj.name)
#a = re.search(ss, original.path)
#pos = a.start()
slash = original.path.find('/',pos+1)
splitpath = original.path[slash+1:len(original.path)]
splitpath = re.sub("\[[0-9]+\]", "", splitpath)
s = splitpath.replace("_dash_",'-')
s = splitpath.replace("_space_","_")
return s
# def writeSumtotal( modelpath,f):
# funclist = moose.wildcardFind(modelpath+'/##[ISA=Function]')
# for func in funclist:
# funcInputs = moose.element(func.path+'/x[0]')
# s = ""
# for funcInput in funcInputs.neighbors["input"]:
# s = s+ "addmsg /kinetics/" + trimPath(funcInput)+ " /kinetics/" + trimPath(moose.element(func.parent)) + " SUMTOTAL n nInit\n"
# f.write(s)
def writeSumtotal( modelpath,f):
error = ""
funclist = moose.wildcardFind(modelpath+'/##[0][ISA=Function]')
s = ""
for func in funclist:
fInfound = True
fOutfound = True
funcInputs = moose.element(func.path+'/x[0]')
if not len(funcInputs.neighbors["input"]):
fInfound = False
error = error +' \n /'+ (moose.element(func)).parent.name+ '/'+moose.element(func).name + ' function doesn\'t have input which is not allowed in genesis. \n This function is not written down into genesis file\n'
if not len(func.neighbors["valueOut"]):
error = error +'Function'+func.path+' has not been connected to any output, this function is not written to genesis file'
fOutfound = False
else:
for srcfunc in func.neighbors["valueOut"]:
if srcfunc.className in ["ZombiePool","ZombieBufPool","Pool","BufPool"]:
functionOut = moose.element(srcfunc)
else:
error = error +' \n Function output connected to '+srcfunc.name+ ' which is a '+ srcfunc.className+' which is not allowed in genesis, this function '+(moose.element(func)).path+' is not written to file'
fOutfound = False
if fInfound and fOutfound:
srcPool = []
for funcInput in funcInputs.neighbors["input"]:
if funcInput not in srcPool:
srcPool.append(funcInput)
if trimPath(funcInput) != None and trimPath(functionOut) != None:
s = "addmsg /kinetics/" + trimPath(funcInput)+ " /kinetics/"+ trimPath(functionOut)+ " SUMTOTAL n nInit\n"
f.write(s)
else:
error = error + '\n Genesis doesn\'t allow same moluecule connect to function mutiple times. \n Pool \''+ moose.element(funcInput).name + '\' connected to '+ (moose.element(func)).path
return error
def writeStimulus(modelpath,f):
error = ""
if len(moose.wildcardFind(modelpath+'/##[0][ISA=StimulusTable]')):
error = error +'\n StimulusTable is not written into genesis. This is in Todo List'
return error
def storePlotMsgs( tgraphs,f):
s = ""
if tgraphs:
for graph in tgraphs:
slash = graph.path.find('graphs')
if not slash > -1:
slash = graph.path.find('graph')
if slash > -1:
foundConc = True
if not ( (graph.path.find('conc1') > -1 ) or
(graph.path.find('conc2') > -1 ) or
(graph.path.find('conc3') > -1 ) or
(graph.path.find('conc4') > -1) ):
foundConc = False
#conc = graph.path.find('conc')
# if conc > -1 :
# tabPath = graph.path[slash:len(graph.path)]
# else:
# slash1 = graph.path.find('/',slash)
# tabPath = "/graphs/conc1" +graph.path[slash1:len(graph.path)]
if foundConc == True:
tabPath = "/"+graph.path[slash:len(graph.path)]
else:
slash1 = graph.path.find('/',slash)
tabPath = "/graphs/conc1" +graph.path[slash1:len(graph.path)]
if len(moose.element(graph).msgOut):
poolPath = (moose.element(graph).msgOut)[0].e2.path
poolEle = moose.element(poolPath)
poolName = poolEle.name
bgPath = (poolEle.path+'/info')
bg = moose.Annotator(bgPath).color
bg = getColorCheck(bg,GENESIS_COLOR_SEQUENCE)
tabPath = re.sub("\[[0-9]+\]", "", tabPath)
s = s+"addmsg /kinetics/" + trimPath( poolEle ) + " " + tabPath + \
" PLOT Co *" + poolName + " *" + str(bg) +"\n";
f.write(s)
def writeplot( tgraphs,f ):
first, second = " ", " "
if tgraphs:
for graphs in tgraphs:
slash = graphs.path.find('graphs')
if not slash > -1:
slash = graphs.path.find('graph')
if slash > -1:
foundConc = True
if not ( (graphs.path.find('conc1') > -1 ) or
(graphs.path.find('conc2') > -1 ) or
(graphs.path.find('conc3') > -1 ) or
(graphs.path.find('conc4') > -1) ):
foundConc = False
if foundConc == True:
tabPath = "/"+graphs.path[slash:len(graphs.path)]
else:
slash1 = graphs.path.find('/',slash)
tabPath = "/graphs/conc1" +graphs.path[slash1:len(graphs.path)]
if len(moose.element(graphs).msgOut):
poolPath = (moose.element(graphs).msgOut)[0].e2.path
poolEle = moose.element(poolPath)
poolAnno = (poolEle.path+'/info')
fg = moose.Annotator(poolAnno).textColor
fg = getColorCheck(fg,GENESIS_COLOR_SEQUENCE)
tabPath = re.sub("\[[0-9]+\]", "", tabPath)
if tabPath.find("conc1") >= 0 or tabPath.find("conc2") >= 0:
first = first + "simundump xplot " + tabPath + " 3 524288 \\\n" + "\"delete_plot.w <s> <d>; edit_plot.D <w>\" " + str(fg) + " 0 0 1\n"
if tabPath.find("conc3") >= 0 or tabPath.find("conc4") >= 0:
second = second + "simundump xplot " + tabPath + " 3 524288 \\\n" + "\"delete_plot.w <s> <d>; edit_plot.D <w>\" " + str(fg) + " 0 0 1\n"
return first,second
def writePool(modelpath,f,volIndex,sceneitems):
error = ""
color = ""
textcolor = ""
for p in moose.wildcardFind(modelpath+'/##[0][ISA=PoolBase]'):
if findCompartment(p) == moose.element('/'):
error = error + " \n "+p.path+ " doesn't have compartment ignored to write to genesis"
else:
slave_enable = 0
if (p.className == "BufPool" or p.className == "ZombieBufPool"):
pool_children = p.children
if pool_children== 0:
slave_enable = 4
else:
for pchild in pool_children:
if not(pchild.className == "ZombieFunction") and not(pchild.className == "Function"):
slave_enable = 4
else:
slave_enable = 0
break
if (p.parent.className != "Enz" and p.parent.className !='ZombieEnz'):
#Assuming "p.parent.className !=Enzyme is cplx which is not written to genesis"
# x = sceneitems[p]['x']
# y = sceneitems[p]['y']
# if sceneitems != None:
# value = sceneitems[p]
# x = calPrime(value['x'])
# y = calPrime(value['y'])
pinfo = p.path+'/info'
if moose.exists(pinfo):
x = sceneitems[p]['x']
y = sceneitems[p]['y']
else:
x = 0
y = 0
error = error + " \n x and y co-ordinates are not specified for `" + p.name+ "` zero will be assigned"+ " \n "
if moose.exists(pinfo):
color = moose.Annotator(pinfo).getField('color')
color = getColorCheck(color,GENESIS_COLOR_SEQUENCE)
textcolor = moose.Annotator(pinfo).getField('textColor')
textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE)
poolsCmpt = findCompartment(p)
geometryName = volIndex[float(poolsCmpt.volume)]
volume = p.volume * NA * 1e-3
if color == "" or color == " ":
color = getRandomColor()
if textcolor == "" or textcolor == " ":
textcolor = getRandomColor()
f.write("simundump kpool /kinetics/" + trimPath(p) + " 0 " +
str(p.diffConst) + " " +
str(0) + " " +
str(0) + " " +
str(0) + " " +
str(p.nInit) + " " +
str(0) + " " + str(0) + " " +
str(volume)+ " " +
str(slave_enable) +
" /kinetics"+ geometryName + " " +
str(color) +" " + str(textcolor) + " " + str(int(x)) + " " + str(int(y)) + " "+ str(0)+"\n")
return error
def getColorCheck(color,GENESIS_COLOR_SEQUENCE):
if isinstance(color, str):
if color.startswith("#"):
color = ( int(color[1:3], 16)
, int(color[3:5], 16)
, int(color[5:7], 16)
)
index = nearestColorIndex(color, GENESIS_COLOR_SEQUENCE)
index = index/2
return index
elif color.startswith("("):
color = eval(color)[0:3]
index = nearestColorIndex(color, GENESIS_COLOR_SEQUENCE)
#This is because in genesis file index of the color is half
index = index/2
return index
else:
index = color
return index
elif isinstance(color, tuple):
color = [int(x) for x in color[0:3]]
index = nearestColorIndex(color, GENESIS_COLOR_SEQUENCE)
return index
elif isinstance(color, int):
index = color
return index
else:
raise Exception("Invalid Color Value!")
def getRandomColor():
ignoreColor= ["mistyrose","antiquewhite","aliceblue","azure","bisque","black","blanchedalmond","blue","cornsilk","darkolivegreen","darkslategray","dimgray","floralwhite","gainsboro","ghostwhite","honeydew","ivory","lavender","lavenderblush","lemonchiffon","lightcyan","lightgoldenrodyellow","lightgray","lightyellow","linen","mediumblue","mintcream","navy","oldlace","papayawhip","saddlebrown","seashell","snow","wheat","white","whitesmoke","aquamarine","lightsalmon","moccasin","limegreen","snow","sienna","beige","dimgrey","lightsage"]
matplotcolor = {}
for name,hexno in matplotlib.colors.cnames.items():
matplotcolor[name]=hexno
k = random.choice(list(matplotcolor.keys()))
if k in ignoreColor:
return getRandomColor()
else:
return k
def writeCompartment(modelpath,compts,f):
index = 0
volIndex = {}
for compt in compts:
if compt.name != "kinetics":
x = xmin+6
y = ymax+1
f.write("simundump group /kinetics/" + compt.name + " 0 " + "blue" + " " + "green" + " x 0 0 \"\" defaultfile \\\n" )
f.write( " defaultfile.g 0 0 0 " + str(int(x)) + " " + str(int(y)) + " 0\n")
i = 0
l = len(compts)
geometry = ""
for compt in compts:
# if isinstance(compt,moose.CylMesh):
# print " 1 "
# size = (compt.volume/compt.numDiffCompts)
# else:
size = compt.volume
ndim = compt.numDimensions
vecIndex = l-i-1
i = i+1
x = xmin+4
y = ymax+1
#geometryname = compt.name
if vecIndex > 0:
geometry = geometry+"simundump geometry /kinetics" + "/geometry[" + str(vecIndex) +"] 0 " + str(size) + " " + str(ndim) + " sphere " +" \"\" white black "+ str(int(x)) + " " +str(int(y)) +" 0\n";
volIndex[float(size)] = "/geometry["+str(vecIndex)+"]"
#geometry = geometry+"simundump geometry /kinetics/" + str(geometryname) + " " +str(size) + " " + str(ndim) + " sphere " +" \"\" white black " + str(int(x)) + " "+str(int(y))+ " 0\n";
#volIndex[float(size)] = geometryname
else:
#geometry = geometry+"simundump geometry /kinetics/" + str(geometryname) + " " + str(size) + " " + str(ndim) + " sphere " +" \"\" white black " + str(int(x)) + " "+str(int(y))+ " 0\n";
geometry = geometry+"simundump geometry /kinetics" + "/geometry 0 " + str(size) + " " + str(ndim) + " sphere " +" \"\" white black " + str(int(x)) + " "+str(int(y))+ " 0\n";
volIndex[float(size)] = "/geometry"
#volIndex[float(size)] = geometryname
f.write(geometry)
writeGroup(modelpath,f)
return volIndex
def writeGroup(modelpath,f):
ignore = ["graphs","moregraphs","geometry","groups","conc1","conc2","conc3","conc4","model","data","graph_0","graph_1","graph_2","graph_3","graph_4","graph_5"]
for g in moose.wildcardFind(modelpath+'/##[0][TYPE=Neutral]'):
if not g.name in ignore:
if trimPath(g) != None:
x = xmin+1
y = ymax+1
f.write("simundump group /kinetics/" + trimPath(g) + " 0 " + "blue" + " " + "green" + " x 0 0 \"\" defaultfile \\\n")
f.write(" defaultfile.g 0 0 0 " + str(int(x)) + " " + str(int(y)) + " 0\n")
def writeHeader(f,maxVol):
simdt = 0.001
plotdt = 0.1
rawtime = 100
maxtime = 100
defaultVol = maxVol
f.write("//genesis\n"
"// kkit Version 11 flat dumpfile\n\n"
"// Saved on " + str(rawtime)+"\n"
"include kkit {argv 1}\n"
"FASTDT = " + str(simdt)+"\n"
"SIMDT = " +str(simdt)+"\n"
"CONTROLDT = " +str(plotdt)+"\n"
"PLOTDT = " +str(plotdt)+"\n"
"MAXTIME = " +str(maxtime)+"\n"
"TRANSIENT_TIME = 2"+"\n"
"VARIABLE_DT_FLAG = 0"+"\n"
"DEFAULT_VOL = " +str(defaultVol)+"\n"
"VERSION = 11.0 \n"
"setfield /file/modpath value ~/scripts/modules\n"
"kparms\n\n"
)
f.write( "//genesis\n"
"initdump -version 3 -ignoreorphans 1\n"
"simobjdump table input output alloced step_mode stepsize x y z\n"
"simobjdump xtree path script namemode sizescale\n"
"simobjdump xcoredraw xmin xmax ymin ymax\n"
"simobjdump xtext editable\n"
"simobjdump xgraph xmin xmax ymin ymax overlay\n"
"simobjdump xplot pixflags script fg ysquish do_slope wy\n"
"simobjdump group xtree_fg_req xtree_textfg_req plotfield expanded movealone \\\n"
" link savename file version md5sum mod_save_flag x y z\n"
"simobjdump geometry size dim shape outside xtree_fg_req xtree_textfg_req x y z\n"
"simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable \\\n"
" geomname xtree_fg_req xtree_textfg_req x y z\n"
"simobjdump kreac kf kb notes xtree_fg_req xtree_textfg_req x y z\n"
"simobjdump kenz CoComplexInit CoComplex nComplexInit nComplex vol k1 k2 k3 \\\n"
" keepconc usecomplex notes xtree_fg_req xtree_textfg_req link x y z\n"
"simobjdump stim level1 width1 delay1 level2 width2 delay2 baselevel trig_time \\\n"
" trig_mode notes xtree_fg_req xtree_textfg_req is_running x y z\n"
"simobjdump xtab input output alloced step_mode stepsize notes editfunc \\\n"
" xtree_fg_req xtree_textfg_req baselevel last_x last_y is_running x y z\n"
"simobjdump kchan perm gmax Vm is_active use_nernst notes xtree_fg_req \\\n"
" xtree_textfg_req x y z\n"
"simobjdump transport input output alloced step_mode stepsize dt delay clock \\\n"
" kf xtree_fg_req xtree_textfg_req x y z\n"
"simobjdump proto x y z\n"
)
def estimateDefaultVol(compts):
maxVol = 0
vol = []
for compt in compts:
vol.append(compt.volume)
if len(vol) > 0:
return max(vol)
return maxVol
def writeNotes(modelpath,f):
notes = ""
#items = moose.wildcardFind(modelpath+"/##[ISA=ChemCompt],/##[ISA=ReacBase],/##[ISA=PoolBase],/##[ISA=EnzBase],/##[ISA=Function],/##[ISA=StimulusTable]")
items = []
items = moose.wildcardFind(modelpath+"/##[0][ISA=ChemCompt]") +\
moose.wildcardFind(modelpath+"/##[0][ISA=PoolBase]") +\
moose.wildcardFind(modelpath+"/##[0][ISA=ReacBase]") +\
moose.wildcardFind(modelpath+"/##[0][ISA=EnzBase]") +\
moose.wildcardFind(modelpath+"/##[0][ISA=Function]") +\
moose.wildcardFind(modelpath+"/##[0][ISA=StimulusTable]")
for item in items:
if not re.search("xfer",item.name):
if moose.exists(item.path+'/info'):
info = item.path+'/info'
notes = moose.Annotator(info).getField('notes')
if (notes):
f.write("call /kinetics/"+ trimPath(item)+"/notes LOAD \ \n\""+moose.Annotator(info).getField('notes')+"\"\n")
def writeFooter1(f):
f.write("\nenddump\n // End of dump\n")
def writeFooter2(f):
f.write("complete_loading\n")
if __name__ == "__main__":
import sys
import os
filename = sys.argv[1]
filepath, filenameWithext = os.path.split(filename)
if filenameWithext.find('.') != -1:
modelpath = filenameWithext[:filenameWithext.find('.')]
else:
modelpath = filenameWithext
moose.loadModel(filename,'/'+modelpath,"gsl")
output = modelpath+"_.g"
written = mooseWriteKkit('/'+modelpath,output)
if written:
print(" file written to ",output)
else:
print(" could be written to kkit format")