mirror of
https://github.com/gsi-upm/soil
synced 2025-01-09 08:11:28 +00:00
Compare commits
No commits in common. "e860bdb922a22da2987fba07dffb81351c0272e5" and "05f7f492332d7ef40e70b36f6c730fe08767d4c6" have entirely different histories.
e860bdb922
...
05f7f49233
@ -3,13 +3,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [0.15.2]
|
|
||||||
### Fixed
|
|
||||||
* Pass the right known_modules and parameters to stats discovery in simulation
|
|
||||||
* The configuration file must exist when launching through the CLI. If it doesn't, an error will be logged
|
|
||||||
* Minor changes in the documentation of the CLI arguments
|
|
||||||
### Changed
|
|
||||||
* Stats are now exported by default
|
|
||||||
## [0.15.1]
|
## [0.15.1]
|
||||||
### Added
|
### Added
|
||||||
* read-only `History`
|
* read-only `History`
|
||||||
|
@ -1 +0,0 @@
|
|||||||
ipython==7.23
|
|
@ -1 +1 @@
|
|||||||
0.15.2
|
0.15.1
|
@ -23,15 +23,13 @@ def main():
|
|||||||
import argparse
|
import argparse
|
||||||
from . import simulation
|
from . import simulation
|
||||||
|
|
||||||
logger.info('Running SOIL version: {}'.format(__version__))
|
logging.info('Running SOIL version: {}'.format(__version__))
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Run a SOIL simulation')
|
parser = argparse.ArgumentParser(description='Run a SOIL simulation')
|
||||||
parser.add_argument('file', type=str,
|
parser.add_argument('file', type=str,
|
||||||
nargs="?",
|
nargs="?",
|
||||||
default='simulation.yml',
|
default='simulation.yml',
|
||||||
help='Configuration file for the simulation (e.g., YAML or JSON)')
|
help='python module containing the simulation configuration.')
|
||||||
parser.add_argument('--version', action='store_true',
|
|
||||||
help='Show version info and exit')
|
|
||||||
parser.add_argument('--module', '-m', type=str,
|
parser.add_argument('--module', '-m', type=str,
|
||||||
help='file containing the code of any custom agents.')
|
help='file containing the code of any custom agents.')
|
||||||
parser.add_argument('--dry-run', '--dry', action='store_true',
|
parser.add_argument('--dry-run', '--dry', action='store_true',
|
||||||
@ -54,15 +52,12 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
logging.basicConfig(level=getattr(logging, (args.level or 'INFO').upper()))
|
logging.basicConfig(level=getattr(logging, (args.level or 'INFO').upper()))
|
||||||
|
|
||||||
if args.version:
|
|
||||||
return
|
|
||||||
|
|
||||||
if os.getcwd() not in sys.path:
|
if os.getcwd() not in sys.path:
|
||||||
sys.path.append(os.getcwd())
|
sys.path.append(os.getcwd())
|
||||||
if args.module:
|
if args.module:
|
||||||
importlib.import_module(args.module)
|
importlib.import_module(args.module)
|
||||||
|
|
||||||
logger.info('Loading config file: {}'.format(args.file))
|
logging.info('Loading config file: {}'.format(args.file))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
exporters = list(args.exporter or ['default', ])
|
exporters = list(args.exporter or ['default', ])
|
||||||
@ -73,10 +68,6 @@ def main():
|
|||||||
exp_params = {}
|
exp_params = {}
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
exp_params['copy_to'] = sys.stdout
|
exp_params['copy_to'] = sys.stdout
|
||||||
|
|
||||||
if not os.path.exists(args.file):
|
|
||||||
logger.error('Please, input a valid file')
|
|
||||||
return
|
|
||||||
simulation.run_from_config(args.file,
|
simulation.run_from_config(args.file,
|
||||||
dry_run=args.dry_run,
|
dry_run=args.dry_run,
|
||||||
exporters=exporters,
|
exporters=exporters,
|
||||||
|
@ -14,6 +14,15 @@ from .utils import open_or_reuse, logger, timer
|
|||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
|
def for_sim(simulation, names, *args, **kwargs):
|
||||||
|
'''Return the set of exporters for a simulation, given the exporter names'''
|
||||||
|
exporters = []
|
||||||
|
for name in names:
|
||||||
|
mod = deserialize(name, known_modules=['soil.exporters'])
|
||||||
|
exporters.append(mod(simulation, *args, **kwargs))
|
||||||
|
return exporters
|
||||||
|
|
||||||
|
|
||||||
class DryRunner(BytesIO):
|
class DryRunner(BytesIO):
|
||||||
def __init__(self, fname, *args, copy_to=None, **kwargs):
|
def __init__(self, fname, *args, copy_to=None, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -29,12 +38,8 @@ class DryRunner(BytesIO):
|
|||||||
super().write(bytes(txt, 'utf-8'))
|
super().write(bytes(txt, 'utf-8'))
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
content = '(binary data not shown)'
|
logger.info('**Not** written to {} (dry run mode):\n\n{}\n\n'.format(self.__fname,
|
||||||
try:
|
self.getvalue().decode()))
|
||||||
content = self.getvalue().decode()
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
pass
|
|
||||||
logger.info('**Not** written to {} (dry run mode):\n\n{}\n\n'.format(self.__fname, content))
|
|
||||||
super().close()
|
super().close()
|
||||||
|
|
||||||
|
|
||||||
@ -94,12 +99,6 @@ class default(Exporter):
|
|||||||
with self.output('{}.sqlite'.format(env.name), mode='wb') as f:
|
with self.output('{}.sqlite'.format(env.name), mode='wb') as f:
|
||||||
env.dump_sqlite(f)
|
env.dump_sqlite(f)
|
||||||
|
|
||||||
def end(self, stats):
|
|
||||||
with timer('Dumping simulation {}\'s stats'.format(self.simulation.name)):
|
|
||||||
with self.output('{}.sqlite'.format(self.simulation.name), mode='wb') as f:
|
|
||||||
self.simulation.dump_sqlite(f)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class csv(Exporter):
|
class csv(Exporter):
|
||||||
'''Export the state of each environment (and its agents) in a separate CSV file'''
|
'''Export the state of each environment (and its agents) in a separate CSV file'''
|
||||||
|
@ -208,13 +208,3 @@ def deserialize(type_, value=None, **kwargs):
|
|||||||
if value is None:
|
if value is None:
|
||||||
return des
|
return des
|
||||||
return des(value)
|
return des(value)
|
||||||
|
|
||||||
|
|
||||||
def deserialize_all(names, *args, known_modules=['soil'], **kwargs):
|
|
||||||
'''Return the set of exporters for a simulation, given the exporter names'''
|
|
||||||
exporters = []
|
|
||||||
for name in names:
|
|
||||||
mod = deserialize(name, known_modules=known_modules)
|
|
||||||
exporters.append(mod(*args, **kwargs))
|
|
||||||
return exporters
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import pickle
|
|||||||
from . import serialization, utils, basestring, agents
|
from . import serialization, utils, basestring, agents
|
||||||
from .environment import Environment
|
from .environment import Environment
|
||||||
from .utils import logger
|
from .utils import logger
|
||||||
from .exporters import default
|
from .exporters import default, for_sim as exporters_for_sim
|
||||||
from .stats import defaultStats
|
from .stats import defaultStats
|
||||||
from .history import History
|
from .history import History
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class Simulation:
|
|||||||
self.topology)
|
self.topology)
|
||||||
|
|
||||||
self._history = History(name=self.name,
|
self._history = History(name=self.name,
|
||||||
backup=False)
|
backup=False)
|
||||||
|
|
||||||
def run_simulation(self, *args, **kwargs):
|
def run_simulation(self, *args, **kwargs):
|
||||||
return self.run(*args, **kwargs)
|
return self.run(*args, **kwargs)
|
||||||
@ -167,16 +167,14 @@ class Simulation:
|
|||||||
logger.setLevel(log_level)
|
logger.setLevel(log_level)
|
||||||
logger.info('Using exporters: %s', exporters or [])
|
logger.info('Using exporters: %s', exporters or [])
|
||||||
logger.info('Output directory: %s', outdir)
|
logger.info('Output directory: %s', outdir)
|
||||||
exporters = serialization.deserialize_all(exporters,
|
exporters = exporters_for_sim(self,
|
||||||
simulation=self,
|
exporters,
|
||||||
known_modules=['soil.exporters',],
|
dry_run=dry_run,
|
||||||
dry_run=dry_run,
|
outdir=outdir,
|
||||||
outdir=outdir,
|
**exporter_params)
|
||||||
**exporter_params)
|
stats = exporters_for_sim(self,
|
||||||
stats = serialization.deserialize_all(simulation=self,
|
stats,
|
||||||
names=stats,
|
**stats_params)
|
||||||
known_modules=['soil.stats',],
|
|
||||||
**stats_params)
|
|
||||||
|
|
||||||
with utils.timer('simulation {}'.format(self.name)):
|
with utils.timer('simulation {}'.format(self.name)):
|
||||||
for stat in stats:
|
for stat in stats:
|
||||||
@ -295,9 +293,6 @@ class Simulation:
|
|||||||
with utils.open_or_reuse(f, 'wb') as f:
|
with utils.open_or_reuse(f, 'wb') as f:
|
||||||
pickle.dump(self, f)
|
pickle.dump(self, f)
|
||||||
|
|
||||||
def dump_sqlite(self, f):
|
|
||||||
return self._history.dump(f)
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
state={}
|
state={}
|
||||||
for k, v in self.__dict__.items():
|
for k, v in self.__dict__.items():
|
||||||
|
@ -74,10 +74,10 @@ class Exporters(TestCase):
|
|||||||
s = simulation.from_config(config)
|
s = simulation.from_config(config)
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
envs = s.run_simulation(exporters=[
|
envs = s.run_simulation(exporters=[
|
||||||
exporters.default,
|
exporters.default,
|
||||||
exporters.csv,
|
exporters.csv,
|
||||||
exporters.gexf,
|
exporters.gexf,
|
||||||
],
|
],
|
||||||
stats=[distribution,],
|
stats=[distribution,],
|
||||||
outdir=tmpdir,
|
outdir=tmpdir,
|
||||||
exporter_params={'copy_to': output})
|
exporter_params={'copy_to': output})
|
||||||
|
Loading…
Reference in New Issue
Block a user