-
Notifications
You must be signed in to change notification settings - Fork 1
/
dispAllExpts.py
191 lines (171 loc) · 8.2 KB
/
dispAllExpts.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
# Floor, Boston, MA 02110-1301, USA.
#
#
'''
*******************************************************************
* File: dispAllExpts.py
* Description:
* Author: Upinder S. Bhalla
* E-mail: bhalla@ncbs.res.in
********************************************************************/
/**********************************************************************
** This program is part of 'HOSS', the
** Hierarchical Optimization for Systems Simulations
** copyright (C) 2019-2020 Upinder S. Bhalla. and NCBS
**********************************************************************/
This script displays simulation results compared with experiments for all
the experiments defined in the optimization configuration file
(a json file). It runs in serial.
'''
from __future__ import print_function
import argparse
import findSim
#from multiprocessing import Pool
import multiprocessing
import json
import time
import numpy as np
results = []
def logResult(result):
# This is called whenever pool(i) returns a result.
# results is modified only by the main process, not the pool workers.
results.append(result)
def worker( fname, returnDict, scoreFunc, modelFile, mapFile, silent, solver, plots, hidePlot, weight ):
score, elapsedTime, diagnostics = findSim.innerMain( fname, scoreFunc = scoreFunc, modelFile = modelFile, mapFile = mapFile, hidePlot = hidePlot, ignoreMissingObj = True, silent = silent, solver = solver, plots = plots )
returnDict[fname] = (score, weight)
def main():
parser = argparse.ArgumentParser( description =
'This script displays simulation results compared with experiments for all the experiments defined in the optimization configuration file (a json file).')
parser.add_argument( 'config', type = str, help='Required: JSON configuration file, typically same file as used for doing the optimization.')
parser.add_argument( '-b', '--blocks', nargs='*', default=[], help='Blocks to display within the JSON file. Defaults to empty, in which case all of them are display. Each block is the string identifier for the block in the JSON file.' )
parser.add_argument( '-m', '--model', type = str, help='Optional: File name for alternative model to run.', default = "" )
parser.add_argument( '-map', '--map', type = str, help='Optional: File name for alternative model mapfile.', default = "" )
parser.add_argument( '-e', '--exptDir', type = str, help='Optional: Location of experiment files.' )
parser.add_argument( '-sf', '--scoreFunc', type = str, help='Optional: Function to use for scoring output of simulation.', default = "" )
parser.add_argument( '--solver', type = str, help='Optional: Numerical method to use for ODE solver. Ignored for HillTau models. Default = "lsoda".', default = "lsoda" )
parser.add_argument( '-p', '--plot', type = str, nargs = '*', help='Optional: Plot specified fields as time-series', default = "" )
parser.add_argument( '-hp', '--hidePlot', action="store_true", help="Flag: default False. When set, turns off plots. Useful to view weighted scores.")
parser.add_argument( '-v', '--verbose', action="store_true", help="Flag: default False. When set, prints all sorts of warnings and diagnostics.")
args = parser.parse_args()
totScore = innerMain( args )
if args.verbose or args.hidePlot:
print( "Final Score = {:.4f}".format( totScore ) )
def innerMain( args ):
try:
with open( args.config ) as json_file:
config = json.load( json_file )
except IOError:
print( "Error: Unable to find HOSS config file: " + args.config )
quit()
requiredDefaultArgs = {
"scoreFunc": "NRMS",
"solver": "LSODA",
"exptDir": "./Expts"
}
baseargs = vars( args )
for key, val in requiredDefaultArgs.items():
if baseargs[key]: # Command line given
continue
elif key in config: # Set up in config file
baseargs[key] = config[key]
else:
baseargs[key] = val
model = config["model"]
if args.model != "":
model = args.model
mapfile = config["map"]
if args.map != "":
mapfile = args.map
b = args.blocks
blockList = []
blocks = config["HOSS"]
if len( b ) == 0:
for bl in blocks:
edict = {}
for pathway, val in bl.items():
if pathway not in ("name", "hierarchyLevel" ):
expt = val.get( "expt" )
if expt:
#edict[key] = [(e, expt[e]["weight"]) for e in expt]
edict[pathway] = expt
#print( "Edict[{}] = {}".format( pathway, expt ) )
blockList.append( edict )
else:
for bl in blocks:
edict = {}
for i in b:
val = bl.get( i )
if val:
expt = val.get( "expt" )
if expt:
#edict[i] = [(e, expt[e]["weight"] ) for e in expt]
edict[i] = expt
blockList.append( edict )
ret = []
manager = multiprocessing.Manager()
totScore = 0.0
numTot = 0
flatScore = 0.0
flatWt = 0.0
for idx, edict in enumerate( blockList ):
sumPathwayScore = 0.0
numPathways = 0
if args.verbose or args.hidePlot:
print( "L{:<3d}".format( idx + 1 ), end = "" )
for pathName, val in edict.items(): # Go through pathways
jobs = []
returnDict = manager.dict()
for f in val: # Iterate through each expt (findsim.json)
fname = baseargs["exptDir"] + "/" + f
p = multiprocessing.Process( target = worker, args = ( fname, returnDict, ), kwargs = dict( scoreFunc = baseargs["scoreFunc"], modelFile = model, mapFile = mapfile, silent = not args.verbose, solver = baseargs["solver"], plots = args.plot, hidePlot = args.hidePlot, weight = val[f]["weight"] ) )
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
sumScore = 0.0
sumWts = 0.0
for key, (score, wt) in returnDict.items():
#print( "{:50s}{:.4f}".format( key, score ) )
sumScore += score * score * wt
sumWts += wt
flatScore += score * score * wt
flatWt += wt
pathwayScore = np.sqrt( sumScore / sumWts )
sumPathwayScore += pathwayScore
numPathways += 1
if args.verbose or args.hidePlot:
print( "{:12s} {:.4f} ".format( pathName, pathwayScore ), end = "" )
meanPathwayScore = sumPathwayScore / numPathways if numPathways > 0 else -1.0
if args.verbose or args.hidePlot:
print( "\nLevel {:<3d} Score = {:.4f}".format( idx + 1, meanPathwayScore ) )
totScore += meanPathwayScore
numTot += 1
if config["hossMethod"]["method"] == "flat":
return np.sqrt( flatScore / flatWt ) if flatWt > 0.0 else -1.0
else:
return totScore / numTot if numTot > 0 else -1.0
#ret.append( pool.apply_async( findSim.innerMain, (fname,), dict( modelFile = model, mapFile = mapfile, hidePlot = False, silent = not args.verbose ), callback = logResult ) )
#time.sleep(5)
#pool.close()
#pool.join()
#print(results)
#finished = [i.get() for i in ret]
#return model, mapfile, edict
# Run the 'main' if this script is executed standalone.
if __name__ == '__main__':
multiprocessing.set_start_method( 'spawn' )
main()