Table Of Contents

Previous topic

sim.py

Next topic

caller.py

This Page

aggregationcaller.py

class AggregationModelCaller(Caller):

Class for constructing and executing aggregation model calls

Attributes:

  • arg: AggregationArg object

def __init__(self, deterministic=False):

Initialize model caller:

>>> from simo.simulation.caller.aggregationcaller import AggregationModelCaller
>>> import numpy
>>> from minimock import Mock
>>> ac = AggregationModelCaller()
>>> ac.arg

def execute(self, model, params, sim, depth):

Execute aggregation model:

>>> def mfunc(arg):
...     arg.results = numpy.array([1.0, None], dtype=float)
>>> sim = Mock('Sim')
>>> class Data(object):
...     def __init__(self):
...         self.active_data_level = 1
...         self.tind = [numpy.array([[0,0,0,0,3],
...                                   [0,0,1,3,5]], dtype=int),
...                      numpy.array([[0,0,0,0,1],
...                                   [0,0,1,1,2],
...                                   [0,0,2,2,3],
...                                   [0,0,3,3,4],
...                                   [0,0,4,4,5]], dtype=int),
...                      numpy.array([[0,0,0,0,1],
...                                   [0,0,1,1,2],
...                                   [0,0,2,2,3],
...                                   [0,0,3,3,4]], dtype=int)]
...         self.vals = [numpy.array([[2.1, 2.2, 2.3, 5.1, 5.2]],
...                                  dtype=float),
...                      numpy.array([[3.1, 3.2, 3.3, 6.2, 6.2]],
...                                  dtype=float),
...                      numpy.array([[4.1, 4.2, 4.3, 7.2, 7.2]],
...                                  dtype=float)]
...     def get_value(self, tind, attrs, forced=False):
...         if attrs == [0]:
...             return self.vals[0], None
...         elif attrs == [1]:
...             return self.vals[1], None
...         elif attrs == [2]:
...             return self.vals[2], None
...         else:
...             return self.vals[0][0], None
...     def get_tind(self, lev, depth, dlev=None, tlev=None, v4all=None,
...                  valuelevel=None, order=None):
...             if dlev is not None:
...                 tlev = dlev
...             else:
...                 tlev = lev
...             self.active_data_level = tlev
...             self.active_dataobjects = self.tind[tlev]
...             return self.tind[tlev], set([])
...     def get_active(self):
...         pass
...     def set_active(self, active):
...         pass
>>> data = Data()
>>> data.set_value = Mock('set_value')
>>> linkage = Mock('Linkage')
>>> linkage.links = {(0,0):{(0,0):{1:[0, 1, 2], 2:[0, 1, 2]},
...                         (0,1):{1:[3, 4], 2:[3,4]},
...                         (1,0):{0:[0], 2:[0]},
...                         (1,1):{0:[0], 2:[1]},
...                         (1,2):{0:[0], 2:[2]},
...                         (1,3):{0:[0], 2:[3]},
...                         (1,4):{0:[0], 2:[]},
...                         (2,0):{0:[0], 1:[0]},
...                         (2,1):{0:[0], 1:[1]},
...                         (2,2):{0:[0], 1:[2]},
...                         (2,3):{0:[0], 1:[3]},
...                        }}
>>> data.linkage = linkage
>>> model = Mock('Model')
>>> model.name = 'sum'
>>> model._v_func = mfunc

>>> op1 = Mock('Operand')
>>> op1.type = 'variable'
>>> op1.variable = (1, 0)
>>> op1.weight = None
>>> op1.default_value = None
>>> op1.default_weight = None

>>> op2 = Mock('Operand')
>>> op2.type = 'variable'
>>> op2.variable = (0, 1)
>>> op2.weight = None
>>> op2.default_value = None
>>> op2.default_weight = None

>>> params = Mock('Parameters')
>>> params.through_level = 1
>>> params.target_ind = (0,3)
>>> params.operands = [op1, op2]
>>> params.condition = None
>>> params.scalar = True

>>> logger = Mock('Logger')
>>> sim.level = 1
>>> sim.data = data
>>> sim.logger = logger
>>> sim.log_name = 'test-log'

Execute model with two operands and no weights (only one value set due to hardwiring the model results to [1.0, None] always:

>>> ac.execute(model, params, sim, 0) 
Called set_value(0, array([[0, 0, 0, 0, 3]]), 3, array([ 1.]), 'sum')
>>> ac._construct_call()
True
>>> ac.arg.target_index
array([[0, 0, 0, 0, 3],
       [0, 0, 1, 3, 5]])
>>> ac.arg.oper_target_index 
deque([array([[0, 0, 0, 0, 1],
              [0, 0, 1, 1, 2],
              [0, 0, 2, 2, 3],
              [0, 0, 3, 3, 4],
              [0, 0, 4, 4, 5]]),
       array([[0, 0, 0, 0, 3],
              [0, 0, 1, 3, 5]])])
>>> ac.arg.oper_data_level
deque([1, 0])
>>> ac.arg.values 
deque([array([ 2.1,  2.2,  2.3,  5.1,  5.2]),
       array([ 3.1,  3.2,  3.3,  6.2,  6.2])])

Execute a vectorized aggregation model:

>>> op1.scalar = False
>>> params.operands = [op1]
>>> params.condition = None
>>> params.through_level = 1
>>> params.target_ind = (0,[3])
>>> ac.execute(model, params, sim, 0)
Called set_value(0, array([[0, 0, 0, 0, 3]]), [3], array([ 1.]), 'sum')

Execute a model with one operand and no weights

>>> params.operands = [op1]
>>> ac._construct_call()
True
>>> ac.arg.target_index
array([[0, 0, 0, 0, 3],
       [0, 0, 1, 3, 5]])
>>> ac.arg.oper_target_index 
deque([array([[0, 0, 0, 0, 1],
              [0, 0, 1, 1, 2],
              [0, 0, 2, 2, 3],
              [0, 0, 3, 3, 4],
              [0, 0, 4, 4, 5]])])
>>> ac.arg.oper_data_level
deque([1])
>>> ac.arg.values 
deque([array([ 2.1,  2.2,  2.3,  5.1,  5.2])])

Execute a model with an aggregation condition

>>> params.condition = [('data', (1, 0, True), (None, None)),
...                     ('value', 2.3),
...                     ('eq', (lambda a,b: a==b))]
>>> params.lowest_operand_level = 1
>>> ac._construct_call()
True
>>> ac.arg.target_index
array([[0, 0, 0, 0, 3],
       [0, 0, 1, 3, 5]])
>>> ac.arg.oper_target_index 
deque([array([[0, 0, 0, 0, 1],
       [0, 0, 1, 1, 2],
       [0, 0, 2, 2, 3],
       [0, 0, 3, 3, 4],
       [0, 0, 4, 4, 5]])])
>>> ac.arg.oper_data_level
deque([1])
>>> ac.arg.values  
deque([array([ ...,  2.3,  ...])])

Execute a model with an aggregation condition for a different level from the operand:

>>> op3 = Mock('Operand')
>>> op3.type = 'variable'
>>> op3.variable = (2, 2)
>>> op3.weight = None
>>> op3.default_value = None
>>> op3.default_weight = None
>>> params.operands = [op3]

>>> params.condition = [('data', (1, 0, True), (None, None)),
...                     ('value', 2.3),
...                     ('eq', (lambda a,b: a==b))]
>>> params.lowest_operand_level = 2
NB! The next one is failing although it shoudn’t. Make it work...
ac._construct_call()
True
ac.arg.target_index
array([[0, 0, 0, 0, 3],
[0, 0, 1, 3, 5]])
ac.arg.oper_target_index # doctest: +NORMALIZE_WHITESPACE
deque([array([[0, 0, 0, 0, 1],
[0, 0, 1, 1, 2], [0, 0, 2, 2, 3], [0, 0, 3, 3, 4]])])
ac.arg.oper_data_level
deque([2])
ac.arg.values
deque([array([ NaN, NaN, 4.3, NaN, 7.2])])

def _construct_call(self):

Construct an aggregation model call.

def _add_operand(self, targetlev, throughlev, tind, oper):

Add a single operand to aggregation arguments.

Parameters:

  • targetlev – target level indice
  • throughlev – through level indice
  • tind – target index, 2d numpy array
  • oper – aggregation operand object

def _call_model(self):

Call aggregation model and extract results.