import numpy
import substance
class SaveData():
'''
Saves morphological structure to file.
'''
def __init__(self, fileName, solver, outputDt, saveFlux=False):
self.solver = solver
self.fileName = fileName
self.fp = None
self.outputDt = outputDt
# Should we store net flux in from parent?
self.saveFlux = saveFlux
def __del__(self):
if(self.fp):
self.fp.close()
def init(self):
header = []
header.append('time;id;parent id;start coords;end coords;radie;dist')
for name in substance.Substance._substanceList:
header.append(';')
header.append(str(name))
if(self.saveFlux):
header.append(";flux")
header.append('\n')
self.fp = open(self.fileName,"w")
self.fp.write(''.join(header))
def close(self):
if(self.fp):
print "Closing ", self.fileName
self.fp.close()
self.fp = None
else:
print "File ", self.fileName, " already closed."
def reopen(self):
self.fp = open(self.fileName,"a+b")
def write(self):
if(self.solver.clock.curTime() % self.outputDt \
>= self.solver.clock.dt / (2 * self.outputDt)):
# print "Skipping write: ", self.solver.clock.curTime()
# Not time to write output, skip
return
if(self.solver.verbose):
print "* Write called: ", self.solver.clock.curTime()
for comp in self.solver.compartments:
line = []
line.append(str(self.solver.clock.curTime()))
line.append(';')
# line.append(str(id(comp)))
line.append(str(comp.id))
line.append(';')
if(comp.parent):
# line.append(str(id(comp.parent)))
line.append(str(comp.parent.id))
line.append(';')
if(comp.parent.parent):
# Start point is parents end point
line.append("(%.5g,%.5g,%.5g)" % \
(comp.parent.endPoint[0], \
comp.parent.endPoint[1], \
comp.parent.endPoint[2]))
else:
# If the parent is soma, start point is outside the sphere
cDir = comp.direction()
line.append("(%.5g,%.5g,%.5g)" % \
(comp.parent.endPoint[0]+comp.parent.radie*cDir[0], \
comp.parent.endPoint[1]+comp.parent.radie*cDir[1], \
comp.parent.endPoint[2]+comp.parent.radie*cDir[2]))
line.append(';')
else:
# No parent, use ID -1 and use own end point for start point
line.append('-1')
line.append(';')
line.append("(%.5g,%.5g,%.5g)" % \
(comp.endPoint[0], \
comp.endPoint[1], \
comp.endPoint[2]))
line.append(';')
# line.append(str(comp.endPoint))
line.append("(%.5g,%.5g,%.5g)" % \
(comp.endPoint[0], comp.endPoint[1], comp.endPoint[2]))
line.append(';')
line.append("%.5g" % (comp.radie))
line.append(';')
# False means do not use recursion - faster.
#line.append("%.5g" % (comp.arcLength(False)))
line.append("%.5g" % (comp.arcLength()))
# We use the sim substance to make sure they are in the right order
for name in substance.Substance._substanceList.iterkeys():
line.append(";")
line.append(str(comp.substances[name].conc))
if(self.saveFlux):
# We are also saving net influx from parent
selfSubs = comp.substances[name]
if(comp.parent):
parentSubs = comp.parent.substances[name]
inFlux = self.solver.transport[selfSubs.id,parentSubs.id] \
* parentSubs.quantity
outFlux = self.solver.transport[parentSubs.id,selfSubs.id] \
* selfSubs.quantity
else:
# No parent, no influx...
inFlux = 0.0
outFlux = 0.0
line.append(";")
line.append("%.5g" % (inFlux-outFlux))
#line.append(str(comp.substances[name].quantity))
line.append('\n')
self.fp.write(''.join(line))