runSolver.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import ivp
  2. import os
  3. import cModel
  4. import sys
  5. import json
  6. import numpy
  7. import time
  8. import scipy.interpolate
  9. defaultValues={\
  10. 'method':'LSODA',\
  11. 'atol':1e-4,\
  12. 'rtol':1e-4,\
  13. 't0':0,\
  14. 'tmax':1,\
  15. 'mode':'IVPSimultaneous',\
  16. 'nt':201,
  17. 'tUnit':'day',\
  18. 'network':'labkey-klimt.json',\
  19. 'startFromRef':'None',\
  20. 'project':'Analysis/Run',\
  21. 'schema':'lists',\
  22. 'query':'runs',\
  23. 'view':'withStrings'}
  24. def get(setup,par):
  25. try:
  26. return setup[par]
  27. except KeyError:
  28. pass
  29. return defaultValues[par]
  30. def parseSetup(setupFile):
  31. with open(setupFile,'r') as f:
  32. setup=json.load(f)
  33. out={}
  34. for p in defaultValues:
  35. out[p]=get(setup,p)
  36. return out
  37. def getScale(setup):
  38. tUnit=setup['tUnit']
  39. if tUnit=='min':
  40. return 1
  41. if tUnit=='hour':
  42. return 60
  43. if tUnit=='day':
  44. return 24*60
  45. if tUnit=='month':
  46. return 24*60*30
  47. if tUnit=='year':
  48. return 24*60*30*365
  49. return 1
  50. def main(parFiles,jobDir):
  51. model=cModel.model()
  52. setupFile=parFiles[0]
  53. modelFile=parFiles[1]
  54. parameterFile=parFiles[2]
  55. model.parse(modelFile,parameterFile)
  56. setup=parseSetup(setupFile)
  57. scale=getScale(setup)
  58. tmax=setup['tmax']*scale
  59. t0,y0,S1=loadSolutionFromRef(setup)
  60. start_time=time.time()
  61. if setup['mode']=='SequentialOdeint':
  62. t,sol,se,s1=ivp.solveSequentialOdeint(model,tmax,setup['nt'],t0,y0,S1)
  63. if setup['mode']=='SimultaneousOdeint':
  64. t,sol,se,s1=ivp.solveSimultaneousOdeint(model,tmax,setup['nt'],t0,y0,S1)
  65. if setup['mode']=='IVP':
  66. t,sol,se,s1=ivp.solveSequential(model,tmax,atol=setup['atol'],\
  67. rtol=setup['rtol'],method=setup['method'],\
  68. t0,y0,S1)
  69. if setup['mode']=='IVPSimultaneous':
  70. t,sol,se,s1=ivp.solveSimultaneous(model,tmax,atol=setup['atol'],\
  71. rtol=setup['rtol'],method=setup['method'],\
  72. t0,y0,S1)
  73. end_time=time.time()
  74. print('Time: {:.3f} s'.format(end_time-start_time))
  75. #store
  76. #interpolate on s1
  77. #s1 has shape ft x n x m
  78. #where ft is LSODE driven number of points
  79. qt,sOut=interpolate(setup,model,t,s1,tmax)
  80. numpy.savetxt(os.path.join(jobDir,'t.txt'),t)
  81. numpy.savetxt(os.path.join(jobDir,'sol.txt'),sol)
  82. numpy.savetxt(os.path.join(jobDir,'se.txt'),se)
  83. numpy.savetxt(os.path.join(jobDir,'qt.txt'),qt)
  84. #this is 3D, so new routines
  85. write3D(os.path.join(jobDir,'sOut.txt'),sOut)
  86. def interpolate(setup,model,t,s1,tmax):
  87. #interpolate on s1
  88. #s1 has shape ft x n x m
  89. #where ft is LSODE driven number of points
  90. sOut=numpy.zeros((setup['nt'],model.n,model.m))
  91. qt=numpy.linspace(0,tmax,setup['nt'])
  92. for i in range(model.n):
  93. for j in range(model.m):
  94. y=s1[:,i,j]
  95. f = scipy.interpolate.interp1d(t, y, kind='cubic')
  96. sOut[:,i,j]=f(qt)
  97. return qt,sOut
  98. def write3D(fName,a):
  99. with open(fName,'w') as f:
  100. f.write('#Shape {}\n'.format(a.shape))
  101. i=0
  102. for data_slice in a:
  103. f.write('#\t Slice {}\n'.format(i))
  104. numpy.savetxt(f,data_slice)
  105. i+=1
  106. def read3D(fName):
  107. new_data=numpy.loadtxt(fName)
  108. #read and parse first row to get shape
  109. with open(fName,'r') as f:
  110. firstLine=f.readline()
  111. shape=firstLine.replace('#Shape ','').\
  112. replace('\n','').\
  113. replace('(','').\
  114. replace(')','').\
  115. split(',')
  116. shape=[int(x) for x in shape]
  117. return new_data.reshape(shape)
  118. if __name__=="__main__":
  119. parFiles=sys.argv[1].split(';')
  120. jobDir=sys.argv[2]
  121. main(parFiles,jobDir)
  122. def loadSolutionFromRef(setup):
  123. if setup['startFromRef']=='None':
  124. return 0,None,None
  125. nixSuite=os.path.join(os.path.expanduser('~'),'software','src','nixSuite')
  126. sys.path.append(os.path.join(nixSuite,'wrapper'))
  127. import nixWrapper
  128. nixWrapper.loadLibrary('labkeyInterface')
  129. import labkeyInterface
  130. import labkeyFileBrowser
  131. net=labkeyInterface.labkeyInterface()
  132. fconfig=os.path.join(os.path.expanduser('~'),'.labkey',setup['network'])
  133. net.init(fconfig)
  134. #debug
  135. net.getCSRF()
  136. #db=labkeyDatabaseBrowser.labkeyDB(net)
  137. fb=labkeyFileBrowser.labkeyFileBrowser(net)
  138. #refFilter={'variable':'runRef','value':setup['startFromRef'],'oper':'eq'}
  139. #ds=db.selectRows(setup['project'],setup['schema'],setup['query'],[refFilter],setup['view']'WithStrings')
  140. #ordering requires the latest to be first
  141. #ref=ds['rows'][0]['runRef']
  142. #parFileString=ds['rows'][0]['parameterFileString']
  143. #parFiles=parFileString.split(';')
  144. ref=setup['startFromRef']
  145. remoteDir=fb.formatPathURL(setup['project'],'/'.join(['jobs',ref]))
  146. localDir=os.path.join(os.path.expanduser('~'),'temp')
  147. inFiles=['t.txt','sol.txt','se.txt','qt.txt','sOut.txt']
  148. #inFiles.extend(parFiles)
  149. for f in inFiles:
  150. localPath=os.path.join(localDir,f)
  151. remotePath='/'.join([remoteDir,f])
  152. fb.readFileToFile(remotePath,localPath)
  153. t=numpy.loadtxt(os.path.join(localDir,'t.txt'))
  154. sol=numpy.loadtxt(os.path.join(localDir,'sol.txt'))
  155. se=numpy.loadtxt(os.path.join(localDir,'se.txt'))
  156. sOut=read3D(os.path.join(localDir,'sOut.txt'))
  157. qt=numpy.loadtxt(os.path.join(localDir,'qt.txt'))
  158. return t[-1],sol[-1],sOut[-1]