mirror of https://github.com/gsi-upm/soil
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.0 KiB
Python
170 lines
6.0 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib
|
|
import sys
|
|
import os
|
|
import logging
|
|
import traceback
|
|
|
|
from .version import __version__
|
|
|
|
try:
|
|
basestring
|
|
except NameError:
|
|
basestring = str
|
|
|
|
from .agents import *
|
|
from . import agents
|
|
from .simulation import *
|
|
from .environment import Environment
|
|
from . import serialization
|
|
from .utils import logger
|
|
from .time import *
|
|
|
|
|
|
def main(cfg='simulation.yml', exporters=None, parallel=None, output="soil_output", *, do_run=False, debug=False, **kwargs):
|
|
import argparse
|
|
from . import simulation
|
|
|
|
logger.info('Running SOIL version: {}'.format(__version__))
|
|
|
|
parser = argparse.ArgumentParser(description='Run a SOIL simulation')
|
|
parser.add_argument('file', type=str,
|
|
nargs="?",
|
|
default=cfg,
|
|
help='Configuration file for the simulation (e.g., YAML or JSON)')
|
|
parser.add_argument('--version', action='store_true',
|
|
help='Show version info and exit')
|
|
parser.add_argument('--module', '-m', type=str,
|
|
help='file containing the code of any custom agents.')
|
|
parser.add_argument('--dry-run', '--dry', action='store_true',
|
|
help='Do not store the results of the simulation to disk, show in terminal instead.')
|
|
parser.add_argument('--pdb', action='store_true',
|
|
help='Use a pdb console in case of exception.')
|
|
parser.add_argument('--debug', action='store_true',
|
|
help='Run a customized version of a pdb console to debug a simulation.')
|
|
parser.add_argument('--graph', '-g', action='store_true',
|
|
help='Dump each trial\'s network topology as a GEXF graph. Defaults to false.')
|
|
parser.add_argument('--csv', action='store_true',
|
|
help='Dump all data collected in CSV format. Defaults to false.')
|
|
parser.add_argument('--level', type=str,
|
|
help='Logging level')
|
|
parser.add_argument('--output', '-o', type=str, default=output or "soil_output",
|
|
help='folder to write results to. It defaults to the current directory.')
|
|
if parallel is None:
|
|
parser.add_argument('--synchronous', action='store_true',
|
|
help='Run trials serially and synchronously instead of in parallel. Defaults to false.')
|
|
|
|
parser.add_argument('-e', '--exporter', action='append',
|
|
default=[],
|
|
help='Export environment and/or simulations using this exporter')
|
|
|
|
parser.add_argument('--only-convert', '--convert', action='store_true',
|
|
help='Do not run the simulation, only convert the configuration file(s) and output them.')
|
|
|
|
parser.add_argument("--set",
|
|
metavar="KEY=VALUE",
|
|
action='append',
|
|
help="Set a number of parameters that will be passed to the simulation."
|
|
"(do not put spaces before or after the = sign). "
|
|
"If a value contains spaces, you should define "
|
|
"it with double quotes: "
|
|
'foo="this is a sentence". Note that '
|
|
"values are always treated as strings.")
|
|
|
|
args = parser.parse_args()
|
|
logger.setLevel(getattr(logging, (args.level or 'INFO').upper()))
|
|
|
|
if args.version:
|
|
return
|
|
|
|
if parallel is None:
|
|
parallel = not args.synchronous
|
|
|
|
exporters = exporters or ['default', ]
|
|
for exp in args.exporter:
|
|
if exp not in exporters:
|
|
exporters.append(exp)
|
|
if args.csv:
|
|
exporters.append('csv')
|
|
if args.graph:
|
|
exporters.append('gexf')
|
|
|
|
if os.getcwd() not in sys.path:
|
|
sys.path.append(os.getcwd())
|
|
if args.module:
|
|
importlib.import_module(args.module)
|
|
if output is None:
|
|
output = args.output
|
|
|
|
|
|
logger.info('Loading config file: {}'.format(args.file))
|
|
|
|
debug = debug or args.debug
|
|
|
|
if args.pdb or debug:
|
|
args.synchronous = True
|
|
|
|
|
|
res = []
|
|
try:
|
|
exp_params = {}
|
|
|
|
if not os.path.exists(args.file):
|
|
logger.error('Please, input a valid file')
|
|
return
|
|
|
|
for sim in simulation.iter_from_config(args.file,
|
|
dry_run=args.dry_run,
|
|
exporters=exporters,
|
|
parallel=parallel,
|
|
outdir=output,
|
|
exporter_params=exp_params,
|
|
**kwargs):
|
|
if args.set:
|
|
for s in args.set:
|
|
k, v = s.split('=', 1)[:2]
|
|
v = eval(v)
|
|
tail, *head = k.rsplit('.', 1)[::-1]
|
|
target = sim
|
|
if head:
|
|
for part in head[0].split('.'):
|
|
try:
|
|
target = getattr(target, part)
|
|
except AttributeError:
|
|
target = target[part]
|
|
try:
|
|
setattr(target, tail, v)
|
|
except AttributeError:
|
|
target[tail] = v
|
|
|
|
if args.only_convert:
|
|
print(sim.to_yaml())
|
|
continue
|
|
if do_run:
|
|
res.append(sim.run())
|
|
else:
|
|
print('not running')
|
|
res.append(sim)
|
|
|
|
except Exception as ex:
|
|
if args.pdb:
|
|
from .debugging import post_mortem
|
|
print(traceback.format_exc())
|
|
post_mortem()
|
|
else:
|
|
raise
|
|
if debug:
|
|
from .debugging import set_trace
|
|
os.environ['SOIL_DEBUG'] = 'true'
|
|
set_trace()
|
|
return res
|
|
|
|
|
|
def easy(cfg, debug=False, **kwargs):
|
|
return main(cfg, **kwargs)[0]
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(do_run=True)
|