Observing agents and logging

There are different ways of observing your agents:

Trade Logging:
ABCE by default logs all trade and creates a SAM or IO matrix.
Manual in agent logging:
An agent is instructed to log a variable with log() or a change in a variable with log_change().
Aggregate Data:
aggregate() save agents possessions and variable aggregated over a group
Panel Data:
panel() creates panel data for all agents in a specific agent group at a specific point in every round. It is set in start.py

How to retrieve the Simulation results is explained in retrieval

Trade Logging

By default ABCE logs all trade and creates a social accounting matrix or input output matrix. Because the creation of the trade log is very time consuming you can change the default behavior in world_parameter.csv. In the column ‘trade_logging’ you can choose ‘individual’, ‘group’ or ‘off’. (Without the apostrophes!).

Manual logging

All functions except the trade related functions can be logged. The following code logs the production function and the change of the production from last year:

output = self.produce(self.inputs)
self.log('production', output)
self.log_change('production', output)

Log logs dictionaries. To log your own variable:

self.log('price', {'input': 0.8, 'output': 1})

Further you can write the change of a variable between a start and an end point with: observe_begin() and observe_end().

class abce.database.Database(id, agent_parameters, simulation_parameters, group, trade_logging, database, check_unchecked_msgs, expiring, perishable, resource_endowment, start_round=None)[source]

Bases: object

The database class

custom_log(method, *args, **kwargs)[source]

send custom logging commands to database plugin, see Database Plugins

log(action_name, data_to_log)[source]

With log you can write the models data. Log can save variable states and and the working of individual functions such as production, consumption, give, but not trade(as its handled automatically). Sending a dictionary instead of several using several log statements with a single variable is faster.

Args:
‘name’(string):
the name of the current action/method the agent executes
data_to_log:
a variable or a dictionary with data to log in the the database

Example:

self.log('profit', profit)

self.log('employment_and_rent',
         {'employment': self['LAB'],
         'rent': self['CAP'],
         'composite': self.composite})

self.log(self.produce_use_everything())
See also:
log_nested():
handles nested dictianaries
log_change():
loges the change from last round

observe_begin():

log_change(action_name, data_to_log)[source]

This command logs the change in the variable from the round before. Important, use only once with the same action_name.

Args:
‘name’(string):
the name of the current action/method the agent executes
data_to_log:
a dictianary with data for the database

Examples:

self.log_change('profit', {'money': self['money']]})
self.log_change('inputs',
    {'money': self.possessions(['money', 'gold', 'CAP', 'LAB')]})
observe_begin(action_name, data_to_observe)[source]

observe_begin and observe_end, observe the change of a variable. observe_begin(…), takes a list of variables to be observed. observe_end(…) writes the change in this variables into the log file

you can use nested observe_begin / observe_end combinations

Args:
‘name’(string):
the name of the current action/method the agent executes
data_to_log:
a dictianary with data for the database

Example:

self.log('production', {'composite': self.composite,
    self.sector: self.final_product[self.sector]})

... different method ...

self.log('employment_and_rent', {
    'employment': self['LAB'],
    'rent': self['CAP']})
observe_end(action_name, data_to_observe)[source]

This command puts in a database called log, whatever values you want values need to be delivered as a dictionary:

Args:
‘name’(string):
the name of the current action/method the agent executes
data_to_log:
a dictianary with data for the database

Example:

self.log('production', {'composite': self.composite,
    self.sector: self.final_product[self.sector]})

... different method ...

self.log('employment_and_rent', {
    'employment': self['LAB'],
    'rent':self['CAP']})

Panel Data

Group.panel_log(variables=[], goods=[], func={}, len=[])[source]

panel_log(.) writes a panel of variables and goods of a group of agents into the database, so that it is displayed in the gui.

Args:
goods (list, optional):
a list of all goods you want to track as ‘strings’
variables (list, optional):
a list of all variables you want to track as ‘strings’
func (dict, optional):
accepts lambda functions that execute functions. e.G. func = lambda self: self.old_money - self.new_money
len (list, optional):
records the length of the list or dictionary with that name.

Example in start.py:

for round in simulation.next_round():
    firms.produce_and_sell()
    firms.panel_log(goods=['money', 'input'],
                variables=['production_target', 'gross_revenue'])
    households.buying()

Aggregate Data

Group.agg_log(variables=[], goods=[], func={}, len=[])[source]

agg_log(.) writes a aggregate data of variables and goods of a group of agents into the database, so that it is displayed in the gui.

Args:
goods (list, optional):
a list of all goods you want to track as ‘strings’
variables (list, optional):
a list of all variables you want to track as ‘strings’
func (dict, optional):
accepts lambda functions that execute functions. e.G. func = lambda self: self.old_money - self.new_money
len (list, optional):
records the length of the list or dictionary with that name.

Example in start.py:

for round in simulation.next_round():
    firms.produce_and_sell()
    firms.agg_log(goods=['money', 'input'],
                variables=['production_target', 'gross_revenue'])
    households.buying()

Retrieval of the simulation results

Agents can log their internal states and the simulation can create panel data. abce.database.

the results are stored in a subfolder of the ./results/ folder. The exact path is in simulation.path. So if you want to post-process your data, you can write a function that changes in to the simulation.path directory and manipulates the CSV files there. The tables are stored as ‘.csv’ files which can be opened with excel.

The same data is also as a sqlite3 database ‘database.db’ available. It can be opened by ‘sqlitebrowser’ in ubuntu.

Example:

In start.py

simulation = abce.Simulation(...)
...
simulation.run()

os.chdir(simulation.path)
firms = pandas.read_csv('aggregate_firm.csv')
...