mirror of
https://github.com/gsi-upm/soil
synced 2025-09-15 04:32:21 +00:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6adc8d36ba | ||
|
c8b8149a17 |
@@ -1,2 +1,4 @@
|
||||
**/soil_output
|
||||
.*
|
||||
__pycache__
|
||||
*.pyc
|
||||
|
11
CHANGELOG.md
11
CHANGELOG.md
@@ -3,6 +3,17 @@ 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).
|
||||
|
||||
## [0.14.7]
|
||||
### Changed
|
||||
* Minor change to traceback handling in async simulations
|
||||
### Fixed
|
||||
* Incomplete example in the docs (example.yml) caused an exception
|
||||
## [0.14.6]
|
||||
### Fixed
|
||||
* Bug with newer versions of networkx (0.24) where the Graph.node attribute has been removed. We have updated our calls, but the code in nxsim is not under our control, so we have pinned the networkx version until that issue is solved.
|
||||
### Changed
|
||||
* Explicit yaml.SafeLoader to avoid deprecation warnings when using yaml.load. It should not break any existing setups, but we could move to the FullLoader in the future if needed.
|
||||
|
||||
## [0.14.4]
|
||||
### Fixed
|
||||
* Bug in `agent.get_agents()` when `state_id` is passed as a string. The tests have been modified accordingly.
|
||||
|
@@ -8,32 +8,8 @@ The advantage of a configuration file is that it is a clean declarative descript
|
||||
Simulation configuration files can be formatted in ``json`` or ``yaml`` and they define all the parameters of a simulation.
|
||||
Here's an example (``example.yml``).
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
---
|
||||
name: MyExampleSimulation
|
||||
max_time: 50
|
||||
num_trials: 3
|
||||
interval: 2
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 100
|
||||
m: 2
|
||||
network_agents:
|
||||
- agent_type: SISaModel
|
||||
weight: 1
|
||||
state:
|
||||
id: content
|
||||
- agent_type: SISaModel
|
||||
weight: 1
|
||||
state:
|
||||
id: discontent
|
||||
- agent_type: SISaModel
|
||||
weight: 8
|
||||
state:
|
||||
id: neutral
|
||||
environment_params:
|
||||
prob_infect: 0.075
|
||||
.. literalinclude:: example.yml
|
||||
:language: yaml
|
||||
|
||||
|
||||
This example configuration will run three trials (``num_trials``) of a simulation containing a randomly generated network (``network_params``).
|
||||
|
35
docs/example.yml
Normal file
35
docs/example.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: MyExampleSimulation
|
||||
max_time: 50
|
||||
num_trials: 3
|
||||
interval: 2
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 100
|
||||
m: 2
|
||||
network_agents:
|
||||
- agent_type: SISaModel
|
||||
weight: 1
|
||||
state:
|
||||
id: content
|
||||
- agent_type: SISaModel
|
||||
weight: 1
|
||||
state:
|
||||
id: discontent
|
||||
- agent_type: SISaModel
|
||||
weight: 8
|
||||
state:
|
||||
id: neutral
|
||||
environment_params:
|
||||
prob_infect: 0.075
|
||||
neutral_discontent_spon_prob: 0.1
|
||||
neutral_discontent_infected_prob: 0.3
|
||||
neutral_content_spon_prob: 0.3
|
||||
neutral_content_infected_prob: 0.4
|
||||
discontent_neutral: 0.5
|
||||
discontent_content: 0.5
|
||||
variance_d_c: 0.2
|
||||
content_discontent: 0.2
|
||||
variance_c_d: 0.2
|
||||
content_neutral: 0.2
|
||||
standard_variance: 1
|
@@ -1,6 +1,6 @@
|
||||
nxsim>=0.1.2
|
||||
simpy
|
||||
networkx>=2.0
|
||||
networkx>=2.0,<2.4
|
||||
numpy
|
||||
matplotlib
|
||||
pyyaml>=5.1
|
||||
|
@@ -1 +1 @@
|
||||
0.14.4
|
||||
0.14.7
|
@@ -20,7 +20,7 @@ def _read_data(pattern, *args, from_csv=False, process_args=None, **kwargs):
|
||||
process_args = {}
|
||||
for folder in glob.glob(pattern):
|
||||
config_file = glob.glob(join(folder, '*.yml'))[0]
|
||||
config = yaml.load(open(config_file))
|
||||
config = yaml.load(open(config_file), Loader=yaml.SafeLoader)
|
||||
df = None
|
||||
if from_csv:
|
||||
for trial_data in sorted(glob.glob(join(folder,
|
||||
@@ -133,7 +133,7 @@ def get_count(df, *keys):
|
||||
def get_value(df, *keys, aggfunc='sum'):
|
||||
if keys:
|
||||
df = df[list(keys)]
|
||||
return df.groupby(axis=1, level=0).agg(aggfunc, axis=1)
|
||||
return df.groupby(axis=1, level=0).agg(aggfunc)
|
||||
|
||||
|
||||
def plot_all(*args, **kwargs):
|
||||
|
@@ -87,7 +87,7 @@ class Environment(nxsim.NetworkEnvironment):
|
||||
@property
|
||||
def network_agents(self):
|
||||
for i in self.G.nodes():
|
||||
node = self.G.node[i]
|
||||
node = self.G.nodes[i]
|
||||
if 'agent' in node:
|
||||
yield node['agent']
|
||||
|
||||
@@ -212,12 +212,12 @@ class Environment(nxsim.NetworkEnvironment):
|
||||
return self[key] if key in self else default
|
||||
|
||||
def get_agent(self, agent_id):
|
||||
return self.G.node[agent_id]['agent']
|
||||
return self.G.nodes[agent_id]['agent']
|
||||
|
||||
def get_agents(self, nodes=None):
|
||||
if nodes is None:
|
||||
return list(self.agents)
|
||||
return [self.G.node[i]['agent'] for i in nodes]
|
||||
return [self.G.nodes[i]['agent'] for i in nodes]
|
||||
|
||||
def dump_csv(self, f):
|
||||
with utils.open_or_reuse(f, 'w') as f:
|
||||
@@ -231,9 +231,9 @@ class Environment(nxsim.NetworkEnvironment):
|
||||
# Workaround for geometric models
|
||||
# See soil/soil#4
|
||||
for node in G.nodes():
|
||||
if 'pos' in G.node[node]:
|
||||
G.node[node]['viz'] = {"position": {"x": G.node[node]['pos'][0], "y": G.node[node]['pos'][1], "z": 0.0}}
|
||||
del (G.node[node]['pos'])
|
||||
if 'pos' in G.nodes[node]:
|
||||
G.nodes[node]['viz'] = {"position": {"x": G.nodes[node]['pos'][0], "y": G.nodes[node]['pos'][1], "z": 0.0}}
|
||||
del (G.nodes[node]['pos'])
|
||||
|
||||
nx.write_gexf(G, f, version="1.2draft")
|
||||
|
||||
|
@@ -216,9 +216,10 @@ class Simulation(NetworkSimulation):
|
||||
try:
|
||||
return self.run_trial(*args, **kwargs)
|
||||
except Exception as ex:
|
||||
c = ex.__cause__
|
||||
c.message = ''.join(traceback.format_exception(type(c), c, c.__traceback__)[:])
|
||||
return c
|
||||
if ex.__cause__ is not None:
|
||||
ex = ex.__cause__
|
||||
ex.message = ''.join(traceback.format_exception(type(ex), ex, ex.__traceback__)[:])
|
||||
return ex
|
||||
|
||||
def to_dict(self):
|
||||
return self.__getstate__()
|
||||
|
@@ -118,9 +118,9 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
elif msg['type'] == 'download_gexf':
|
||||
G = self.trials[ int(msg['data']) ].history_to_graph()
|
||||
for node in G.nodes():
|
||||
if 'pos' in G.node[node]:
|
||||
G.node[node]['viz'] = {"position": {"x": G.node[node]['pos'][0], "y": G.node[node]['pos'][1], "z": 0.0}}
|
||||
del (G.node[node]['pos'])
|
||||
if 'pos' in G.nodes[node]:
|
||||
G.nodes[node]['viz'] = {"position": {"x": G.nodes[node]['pos'][0], "y": G.nodes[node]['pos'][1], "z": 0.0}}
|
||||
del (G.nodes[node]['pos'])
|
||||
writer = nx.readwrite.gexf.GEXFWriter(version='1.2draft')
|
||||
writer.add_graph(G)
|
||||
self.write_message({'type': 'download_gexf',
|
||||
@@ -130,9 +130,9 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
elif msg['type'] == 'download_json':
|
||||
G = self.trials[ int(msg['data']) ].history_to_graph()
|
||||
for node in G.nodes():
|
||||
if 'pos' in G.node[node]:
|
||||
G.node[node]['viz'] = {"position": {"x": G.node[node]['pos'][0], "y": G.node[node]['pos'][1], "z": 0.0}}
|
||||
del (G.node[node]['pos'])
|
||||
if 'pos' in G.nodes[node]:
|
||||
G.nodes[node]['viz'] = {"position": {"x": G.nodes[node]['pos'][0], "y": G.nodes[node]['pos'][1], "z": 0.0}}
|
||||
del (G.nodes[node]['pos'])
|
||||
self.write_message({'type': 'download_json',
|
||||
'filename': self.config['name'] + '_trial_' + str(msg['data']),
|
||||
'data': nx.node_link_data(G) })
|
||||
@@ -271,4 +271,4 @@ def main():
|
||||
parser.add_argument('--verbose', '-v', help='verbose mode', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(name=args.name, port=(args.port[0] if isinstance(args.port, list) else args.port), verbose=args.verbose)
|
||||
run(name=args.name, port=(args.port[0] if isinstance(args.port, list) else args.port), verbose=args.verbose)
|
||||
|
@@ -186,7 +186,7 @@ class TestMain(TestCase):
|
||||
with utils.timer('serializing'):
|
||||
serial = s.to_yaml()
|
||||
with utils.timer('recovering'):
|
||||
recovered = yaml.load(serial)
|
||||
recovered = yaml.load(serial, Loader=yaml.SafeLoader)
|
||||
with utils.timer('deleting'):
|
||||
del recovered['topology']
|
||||
assert config == recovered
|
||||
@@ -240,7 +240,7 @@ class TestMain(TestCase):
|
||||
env[0, 0, 'testvalue'] = 'start'
|
||||
env[0, 10, 'testvalue'] = 'finish'
|
||||
nG = env.history_to_graph()
|
||||
values = nG.node[0]['attr_testvalue']
|
||||
values = nG.nodes[0]['attr_testvalue']
|
||||
assert ('start', 0, 10) in values
|
||||
assert ('finish', 10, None) in values
|
||||
|
||||
|
Reference in New Issue
Block a user