.. _sim-py: ###### sim.py ###### ************************ class Simulator(object): ************************ SIMO simulator module. Attributes: - _logger: simulation log, logger instance - _log_name: log name, string - lexicon: simulation lexicon, Lexicon instance - _ctrl: simulation main controls, SimControl instance - _callers: model and table caller instances, dictionary with model/table type as key and caller instance as value - _evaluator: condition evaluator, ConditionEvaluator instance - _input_db: input database: DataDB instance - _data_db: data database: DataDB instance - _operation_db: operation database: OperationDB instance - data: data matrix handler, Handler instance - _iterations: number of iterations, integer - period: current period, integer - timespan: current time span, Timespan object - chain_index: current model chain index, integer - _chain_type: current model chain type: 'init', 'loop' or 'operation' - _chains: model chains of the current time span in a dictionary, chain type as key, list of chains as value - _forced_operations: forced operations for current simulation units, dictionary - level: current evaluation level, integer - main_level: simulation main level, integer - _tasks: currently active tasks in a list - task: currently active task object - value_fixing: value fixing, boolean - _block_growth: target index of objects for which growth is blocked - _block_all: target index of objects that are totally blocked - terminate: terminate simulation, boolean Some of the caller classes need to access certain simulator data attributes. This access is granted with properties that reveal the needed attributes. Properties: - operation_memory def __init__(self, logger, logname, lexicon, ctrl, input_db, data_db, operation_db, warnings, maxunitcount, obj_count_multiplier, branch_count, no_op_branch, separate_branching_groups, branch_limit, max_res_objs, max_errors, max_simunit_errors, deterministic, track_prices, do_forced_ops, copy2iters, create_branch_desc, cache_dir): ============================================================================================================================================================================================================================================================================================================================================ :: >>> import numpy as np >>> import datetime as dt >>> from minimock import Mock >>> execfile('simulation/test/mocks4sim.py') >>> import simo.simulation.sim >>> simo.simulation.sim.Handler = fake_handler.Handler Construct simulator instance:: >>> from simo.simulation.sim import Simulator >>> sim = Simulator(logger, 'test-log', 'simulation', lexicon, ctrl, ... input_db, data_db, operation_db, True, 11, 1, 1, ... False, False, 100, 50, 10, 1, False, True, True, False, ... True, 'cache') def _reset(self): ================= Reset simulator, erase all information about past simulation and set all settings to default. def simulate(self, iterations): =============================== Run simulation with current simulation setup and data matrix, but substitute data handler and evaluator at this point with mock objects :: >>> sim.data = data >>> sim.data.matrix.iterations = 1 >>> sim._evaluator = evaluator >>> sim.simulate(1) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '6 simulation units divided into 1 sets') Called Logger.log_message( 'test-log', 'DEBUG', "Simulating ids: [(u'1', u'1'), (u'2', u'2'), (u'3', u'3'), (u'4', u'4'), (u'5', u'5'), ('6', '6')]") Called HandlerCreator.Handler( 1, , 5, 1, 1, {'bgroup1': [[(None, {'btask1': ['cond1']})], True]}, False, False, , 6, 1, 100) Called Logger.log_message( 'test-log', 'INFO', 'filling simulation data matrix...') Called InputDB.fill_matrix( , 1, [(u'1', u'1'), (u'2', u'2'), (u'3', u'3'), (u'4', u'4'), (u'5', u'5'), ('6', '6')]) Called Handler.get_tind(0, 0) Called Handler.set_value(0, array([[0, 0, 0, 0, 0]]), 3, array([ 0.])) Called Handler.set_value(0, array([[0, 0, 1, 0, 0]]), 3, array([ 0.])) Called Handler.set_value(0, array([[0, 0, 2, 0, 0]]), 3, array([ 0.])) Called Logger.log_message('test-log', 'INFO', 'matrix filling complete') Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2000...1...1..., ...2000...1...1..., ...2000...1...1...], dtype=object), set_init_date=True) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2000., 2000., 2000.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 1., 1., 1.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 1., 1., 1.])) Called Logger.log_message( 'test-log', 'INFO', 'simulating iterations 1..1 for set 1/1 with 6 units') Called Handler.get_tind(1, 0) Called Handler.get_tind(0, 0) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, 5) Called InputDB.get_level_ind() Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, , ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(1, 0) Called Handler.get_tind(1, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , 1, 1, 0, , ) Called Handler.block(1, 0, array([[0, 0, 0, 0, 0]]), True) Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(0, 0) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called InputDB.get_level_ind() Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, , ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called InputDB.get_level_ind() Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, , ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2004...12...31..., ...2004...12...31..., ...2004...12...31...], dtype=object)) Called DataDB.add_data_from_matrix( , , , , set([(0, 0, 0)]), set([]), 1, , False, 0) Called DataDB.add_branching_info( 1, , , 0) Called Handler.brancher.reset_binfo() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2000...1...2..., ...2000...1...2..., ...2000...1...2...], dtype=object)) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2000., 2000., 2000.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 1., 1., 1.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 2., 2., 2.])) Called Handler.release(None, None, None, False, True) Called Handler.check_errors(1) Called Handler.block(1, 0, array([[0, 0, 0]]), True) Called Logger.log_message('test-log', 'INFO', 'creating branch descriptions') Called DataDB.fill_branch_desc_table([u'1', u'2', u'3', u'4', u'5', '6'], 0) Called Logger.log_message('test-log', 'INFO', 'set simulated in 00:00:...') Called Logger.log_message('test-log', 'INFO', 'avg. time per unit 00:00:...') Called Logger.log_message('test-log', 'INFO', 'avg. time per set 00:00:...') Called Logger.log_message('test-log', 'INFO', 'total time 00:00:...') NB: The last call to Handler.set_date adds a single day to to initial dates. As the Handler is a mock object the previous call didn't really change the dates, hence the year discrepancy between the calls. def _evaluate_steps(self, forceops): ==================================== Evaluate number of timesteps with possible stopping conditions, simulation chains, forced operations and/or operation chains and update simulator state:: >>> sim._start_step = 0 >>> sim._evaluate_steps(False) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.get_tind(1, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , 1, 1, 0, , ) Called Handler.block(1, 0, array([[0, 0, 0, 0, 0]]), True) Called InputDB.get_level_ind() Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, , ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called InputDB.get_level_ind() Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, , ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2004...12...31..., ...2004...12...31..., ...2004...12...31...], dtype=object)) Called DataDB.add_data_from_matrix( , , , , set([(0, 0, 0)]), set([]), 1, , False, 0) Called DataDB.add_branching_info( 1, , , 0) Called Handler.brancher.reset_binfo() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2000...1...2..., ...2000...1...2..., ...2000...1...2...], dtype=object)) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2000., 2000., 2000.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 1., 1., 1.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 2., 2., 2.])) def _evaluate_chains(self, chaintype, ind=None): ================================================ The model chains are evaluated so that the method goes through the top level 'task' elements and calls a method to process each of the task elements. chaintype is one of 'init', 'simulation', 'operation' or 'forced_operation'. def _evaluate_task(self, task, depth): ====================================== Method evaluates a task element of a model chain and moves on recursively to any subtasks if there are subtasks. If condition element is found, evaluate_expression Method is called and if model element is found, evaluate_model Method is called. Evaluate a task with no condition, model or subtasks:: >>> task = Mock('Task') >>> task.condition = None >>> task.model = None >>> task.path = 'path/of/this/task' >>> task.subtasks = [] >>> task.task.path = 'path/of/this/task' >>> sim._evaluate_task(task, 0) Evaluate a task with condition:: >>> task.condition = Mock('Expression') >>> sim._evaluate_task(task, 0) # doctest: +ELLIPSIS Called Handler.get_tind(None, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , None, 1, 0, ) Called Handler.block(None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.release( None, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Evaluate a task with subtasks:: >>> task = Mock('Task') >>> task.condition = None >>> task.model = None >>> task.path = 'path/of/this/task' >>> subtask_1 = Mock('Task') >>> subtask_1.condition = None >>> subtask_1.model = None >>> subtask_1.path = 'path/of/this/task' >>> subtask_1.subtasks = [] >>> subtask_2 = Mock('Task') >>> subtask_2.condition = None >>> subtask_2.model = None >>> subtask_2.path = 'path/of/this/task' >>> subtask_2.subtasks = [subtask_1, subtask_1] >>> task.subtasks = [subtask_1, subtask_2] >>> sim._evaluate_task(task, 0) # doctest: +ELLIPSIS def _evaluate_subtasks(self, task, depth): ========================================== Evaluate a subtask and all it's possible subtasks. In this example the task is a so-called 'branch_task', which means that it is processed in a bit different way than normal task:: >>> task = Mock('Task') >>> task.type = 'branch_task' >>> task.path = 'path/of/this/task' >>> task.condition = None >>> subtask = Mock('Task') >>> subtask.model = None >>> subtask.path = 'path/of/this/task' >>> subtask.condition = None >>> subtask.subtasks = [] >>> sim._tasks = [task] >>> task.subtasks = [subtask] >>> task.branch_conditions = [('branch1', 'C1'), ('branch2', 'C2')] >>> task.branching_group = 'bgroup1' >>> task.branching_group_part = 0 >>> sim._evaluate_subtasks(task, 0) # doctest: +ELLIPSIS Called Handler.get_tind(None, 1) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 'C1', None, 1, 1, , ) Called Handler.block(None, 1, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.brancher.start( , 'branch1', , , 1, 1, , ) Called Handler.brancher.stop( 'branch1', , , 1, 1, , , , 0, 2, [], []) Called Handler.release( None, 1, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(None, 1) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 'C2', None, 1, 1, , ) Called Handler.block(None, 1, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.brancher.start( , 'branch2', , , 1, 1, , ) Called Handler.brancher.stop( 'branch2', , , 1, 1, , , , 0, 2, [], []) Called Handler.release( None, 1, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) def _evaluate_model(self, model, depth): ======================================== Evaluate a model stored in a model chain. Models can be of types: 'prediction', 'aggregation', 'operation', 'management', 'geo_table' and 'parameter_table'. def _evaluate_expression(self, expr, level, depth=0): ===================================================== Evaluate a condition expression. Expressions are in postfix deque items and are evaluated with a postfix evaluator. Return target index of all blocked objects and boolean value True if all evaluation level objects are blocked and False if not. def _evaluate_stop_condition(self): =================================== Evaluate simulation stopping condition and stop simulation if condition evaluates True for all simulation level objects. Block the objects for which the condition was met:: >>> sim._evaluator.evaluate.mock_returns = np.array([True, False, True], ... dtype=bool) >>> sim._evaluate_stop_condition() # doctest: +ELLIPSIS Called Handler.get_tind(1, 0) Called Handler.get_tind(1, 0) Called Evaluator.evaluate( , array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), , 1, 1, 0, , ) Called Handler.block( 1, 0, array([[0, 0, 0, 0, 0], [0, 0, 2, 0, 0]]), True) False def _evaluate_end_date(self): ============================= Check if any of the main level objects have passed the simulation ending date. Block objects that have passed the ending date:: >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2001,1,1), ... dt.date(1999,1,1), ... dt.date(2000,1,1)], dtype=dt.date) >>> sim.timespan.ending.target = dt.date(2000,1,1) >>> sim._evaluate_end_date() # doctest: +ELLIPSIS Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 0., 1., 0.])) Called Handler.block( 1, 0, array([[0, 0, 0, 0, 0], [0, 0, 2, 0, 0]]), True) False >>> sim._block_all array([[0, 0, 0, 0, 0], [0, 0, 2, 0, 0]]) >>> sim.timespan.ending.target = dt.date(2002,1,1) >>> sim._evaluate_end_date() # doctest: +ELLIPSIS Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 1., 3., 2.])) False >>> sim._block_all >>> sim.timespan.ending.target = dt.date(1998,1,1) >>> sim._evaluate_end_date() # doctest: +ELLIPSIS Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 0., 0., 0.])) Called Handler.block( 1, 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), True) True >>> sim._block_all array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]) def _do_grow(self): =================== Check if growth should be calculated for the current time step, ie. should the 'simulation' model chains be evaluated, and block objects for which the growth simulation should be passed. If time step unit is year and length is at least a year, this check has to be done only during the first time step. If time step is less than one year, the growth season should be considered and the sub year steps should be distributed evenly to the growth season. :: >>> sim.period = 0 >>> sim._ctrl.growth_season_end_month = 7 >>> sim._ctrl.growth_season_end_day = 1 >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2000,6,30), ... dt.date(2000,7,2), ... dt.date(1999,7,2)], dtype=dt.date) >>> sim._do_grow() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(0, 0) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 5., 4., 4.])) True >>> sim._block_growth Test a situation with "end_date" as timespan ending type, first timestep out of more than one timesteps and one (the third) unit is past current year's growth season and the end date is at the end of next year's growth season. In this case none of the three units should be blocked as the possible time step reductions have already been done in _evaluate_end_date. All units with timestep greater than 0 should be simulated. :: >>> sim.period = 0 >>> sim._end_step = 2 >>> sim._ctrl.growth_season_end_month = 7 >>> sim._ctrl.growth_season_end_day = 31 >>> sim.timespan.ending.type = "end_date" >>> sim.timespan.ending.target = dt.date(2010, 7, 31) >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2002,8,20), ... dt.date(2005,8,20), ... dt.date(2009,8,20)], dtype=dt.date) >>> sim.data.get_value.mock_returns = (np.array([5.,5.,1.], dtype=float), ... None) >>> sim._do_grow() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(0, 0) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 5., 5., 1.])) True >>> sim._block_growth Test again a situation with "steps" as timespan ending type and all units have timesteps greater than 1 :: >>> sim._ctrl.growth_season_end_month = 7 >>> sim._ctrl.growth_season_end_day = 1 >>> sim.timespan.ending.type = "steps" >>> sim.timespan.ending.target = dt.date(1998, 1, 1) >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2000,7,2), ... dt.date(1999,7,2), ... dt.date(2010,7,2)], dtype=dt.date) >>> sim.data.get_value.mock_returns = (np.array([5.,4.,4.], dtype=float), ... None) >>> sim._reset() >>> sim.data = data >>> sim._do_grow() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_tind(0, 0) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 4., 3., 3.])) True >>> sim._block_growth def _do_force_operations(self): ========================================= Check if forced operations should be done to any of the current simulation units during the current timespan :: >>> sim._operation_db.fill_dictionary.mock_returns = { ... u'2': 'forced operations for unit 2', ... u'3': 'forced operations for unit 3', ... u'5': 'forced operations for unit 5'} >>> sim.lexicon.get_level_name.mock_returns = u'comp_unit' >>> sim.data.get_id.mock_returns = [u'2', u'3', u'4'] >>> sim.data.get_tind.mock_returns = (np.array([[0, 0, 0, 0, 0], ... [0, 0, 1, 0, 0], ... [0, 0, 2, 0, 0]], ... dtype=int), None) >>> timespan.forced_operations = True >>> chain1 = Mock('Chain') >>> chain2 = Mock('Chain') >>> chain3 = Mock('Chain') >>> chain1.name = 'Chain one' >>> chain2.name = 'Chain two' >>> chain3.name = 'Chain three' >>> mcc = Mock('ModelChainCollection') >>> mcc.chains = [chain1, chain2] >>> mcc2 = Mock('ModelChainCollection') >>> mcc2.chains = [chain3] >>> timespan.chain_collections['forced_operation'] = [mcc, mcc2] >>> sim.timespan = timespan >>> sim._do_force_operations() # doctest: +NORMALIZE_WHITESPACE Called Lexicon.get_level_name(1) Called OperationDB.fill_dictionary( u'comp_unit', [(u'1', u'1'), (u'2', u'2'), (u'3', u'3'), (u'4', u'4'), (u'5', u'5'), ('6', '6')]) Called Handler.get_tind(1, 0) Called Handler.get_id( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_init_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) True >>> sim._forced_operations[u'2'] 'forced operations for unit 2' >>> sim._forced_operations[u'3'] 'forced operations for unit 3' >>> sim._forced_operations[u'5'] 'forced operations for unit 5' >>> sim._forced_chain_index [{'Chain two': 1, 'Chain one': 0}, {'Chain three': 0}] def _evaluate_forced_operations(self): ============================================ Evaluate the forced operations for the current units. Forced operations can be operation that actually have happened when simulating from past to present (updating simulations) or operations can be forced to simulation units for some other reason :: >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2005,7,2), ... dt.date(2004,7,2), ... dt.date(2015,7,2)], dtype=dt.date) >>> fop = Mock('ForcedOperation') >>> fop.id = u'2' >>> fop.level = u'comp_unit' >>> fop.name = u'clearcut' >>> fop.timing_type = 'step' >>> fop.time_step = 1 >>> fop.date = dt.date(2006,1,1) >>> fop.step_unit = 'year' >>> fop.chain_names = ['Chain two', 'Chain three'] >>> fop.chain_indices = None >>> fop.parameters = None >>> fop.data_values = {(u'comp_unit', u'FORCED_OP_VAR'): 100.} >>> sim._forced_operations = {(0,0,u'2'): [fop]} >>> sim.data.get_id.mock_returns = ['2','5','6'] >>> sim._evaluate_chains = Mock('mock_evaluate_chains') >>> sim._evaluate_forced_operations() Called Handler.get_tind(1, 0) Called Handler.get_id( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.block( 1, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), True) Called Lexicon.get_variable_ind(u'comp_unit', u'FORCED_OP_VAR') Called Handler.get_value(array([[0, 0, 0, 0, 0]]), 0) Called Handler.set_value(1, array([[0, 0, 0, 0, 0]]), 0, 100.0) Called mock_evaluate_chains('forced_operation', [[1], [0]]) Called Lexicon.get_variable_ind(u'comp_unit', u'FORCED_OP_VAR') Called Handler.get_value(array([[0, 0, 0, 0, 0]]), 0) Called Handler.set_value(1, array([[0, 0, 0, 0, 0]]), 0, 4.0) Called Handler.release( 1, 0, array([[0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), True, False) False Set the current dates so that forced operations should not be evaluated yet :: >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2000,7,2), ... dt.date(1999,7,2), ... dt.date(2005,7,2)], dtype=dt.date) >>> sim._forced_operations = {(0,0,u'2'): [fop]} >>> sim._blocked_forced = np.array([], dtype=int) >>> sim._blocked_forced.shape = (0, 5) >>> sim._evaluate_forced_operations() Called Handler.get_tind(1, 0) Called Handler.get_id( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) True Set the current dates so that forced operations should already have been evaluated :: >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2015,7,2), ... dt.date(2014,7,2), ... dt.date(2025,7,2)], dtype=dt.date) >>> sim._blocked_forced = np.array([], dtype=int) >>> sim._blocked_forced.shape = (0, 5) >>> sim._evaluate_forced_operations() Called Handler.get_tind(1, 0) Called Handler.get_id( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) True def _get_num_of_steps(self): ============================ Get the maximum number of timesteps for the current timespan. As each simulation unit might have different date stamp, the number of time steps will be the maximum over all units.:: >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(2005,7,2), ... dt.date(2004,7,2), ... dt.date(2015,7,2)], dtype=dt.date) >>> sim.timespan.ending.type = 'end_date' >>> sim._get_num_of_steps() # doctest: +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Logger.log_message( 'test-log', 'INFO', 'all simulation units are past simulation ending date (1998-01-01), time step of timespan n.o 1 set to 0') True >>> sim.timespan.ending.target = dt.date(2020,1,1) >>> sim._get_num_of_steps() Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Logger.log_message( 'test-log', 'WARNING', 'The number of years (16) is not divisible with the given time step (5). Forcably rounding up.') True >>> sim._end_step 4 >>> sim.timespan.ending.type = 'steps' >>> sim.timespan.ending.target = 10 >>> sim._get_num_of_steps() True >>> sim._end_step 10 def _update(self): ================== Update simulator state and move to next time step:: >>> sim._update(to='current period end') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2, array([ 5., 4., 4.])) Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_value( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 2) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2009...7...1..., ...2007...7...1..., ...2018...7...1...], dtype=object)) >>> sim.period 0 Note that the 'next period beginning' update only adds a single day to the current day. That's because the 'current period end' is assumed to be made before this call. However, as the mock object used here doesn't really change the date, a single day is here added to the initial date. :: >>> sim._update(to='next period beginning') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2005...7...3..., ...2004...7...3..., ...2015...7...3...], dtype=object)) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2005., 2004., 2015.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 7., 7., 7.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 3., 3., 3.])) >>> sim.period 1 def _set_data(self, iterations, start, ids): ============================================ Create data handler if first simulation run and reset existing handler otherwise. Fill data matrix from input database and store init variable values to data matrix iterations -- number of iterations, int start -- starting iteration round ids -- list of simulation unit id strings :: >>> sim.data.matrix.iterations = 1 >>> sim._ctrl.init_variables = [((1,1),0.0), ((0,5),15.0)] >>> sim._set_data(1, 0, ['1', '2', '3']) # doctest: +ELLIPSIS Called Handler.reset() Called Logger.log_message( 'test-log', 'INFO', 'filling simulation data matrix...') Called InputDB.fill_matrix(, 1, ['1', '2', '3']) Called Handler.get_tind(0, 0) Called Handler.set_value(0, array([[0, 0, 0, 0, 0]]), 3, array([ 0.])) Called Handler.set_value(0, array([[0, 0, 1, 0, 0]]), 3, array([ 0.])) Called Handler.set_value(0, array([[0, 0, 2, 0, 0]]), 3, array([ 0.])) Called Handler.get_tind(0, 0) Called Handler.set_value( 0, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), [5], [15.0]) Called Handler.get_tind(1, 0) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), [1], [0.0]) Called Logger.log_message('test-log', 'INFO', 'matrix filling complete') def _divide_data(self, iterations, idlist, indseq): =================================================== Divide the simulation target data into reasonable blocks:: >>> sim._iterations = 2 >>> sim._divide_data([u'1',u'2',u'3',u'4'], None) Called InputDB.get_ids('data', 1, both=True, id_list=[u'1', u'2', u'3', u'4']) Called Logger.log_message( 'test-log', 'INFO', '4 simulation units divided into 1 sets') [([(u'1', u'1'), (u'2', u'2'), (u'3', u'3'), (u'4', u'4')], 2, 0)] >>> sim._iterations = 1 >>> sim._divide_data(None, (2,4)) Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '3 simulation units divided into 1 sets') [([(u'2', u'2'), (u'3', u'3'), (u'4', u'4')], 1, 0)] >>> sim._iterations = 3 >>> sim._divide_data(None, None) # doctest: +NORMALIZE_WHITESPACE Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '6 simulation units divided into 2 sets') [([(u'1', u'1'), (u'2', u'2'), (u'3', u'3')], 3, 0), ([(u'4', u'4'), (u'5', u'5'), ('6', '6')], 3, 0)] >>> sim._iterations = 5 >>> sim._divide_data(None, None) # doctest: +NORMALIZE_WHITESPACE Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '6 simulation units divided into 3 sets') [([(u'1', u'1'), (u'2', u'2')], 5, 0), ([(u'3', u'3'), (u'4', u'4')], 5, 0), ([(u'5', u'5'), ('6', '6')], 5, 0)] >>> sim._iterations = 6 >>> sim._divide_data(None, None) # doctest: +NORMALIZE_WHITESPACE Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '6 simulation units divided into 6 sets') [([(u'1', u'1')], 6, 0), ([(u'2', u'2')], 6, 0), ([(u'3', u'3')], 6, 0), ([(u'4', u'4')], 6, 0), ([(u'5', u'5')], 6, 0), ([('6', '6')], 6, 0)] >>> sim._iterations = 10 >>> sim._divide_data(None, None) # doctest: +NORMALIZE_WHITESPACE Called InputDB.get_ids('data', 1, both=True, id_list=None) Called Logger.log_message( 'test-log', 'INFO', '6 simulation units divided into 6 sets') [([(u'1', u'1')], 10, 0), ([(u'2', u'2')], 10, 0), ([(u'3', u'3')], 10, 0), ([(u'4', u'4')], 10, 0), ([(u'5', u'5')], 10, 0), ([('6', '6')], 10, 0)] Info message should be generated if invalid simulation units are given in idlist:: >>> sim._input_db.get_ids.returns = [(u'1', u'1') ,(u'2', u'2'), ... (u'3', u'3'), (u'4', u'4'), (u'5', u'5')] >>> sim._iterations = 2 >>> sim._divide_data([u'2',u'3',u'49',u'139'], None) ... # doctest: +NORMALIZE_WHITESPACE Called InputDB.get_ids( 'data', 1, both=True, id_list=[u'2', u'3', u'49', u'139']) Called Logger.log_message( 'test-log', 'INFO', u'following simulation units were not found in input database: 49, 139') Called Logger.log_message( 'test-log', 'INFO', '2 simulation units divided into 1 sets') [([(u'2', u'2'), (u'3', u'3')], 2, 0)] def _set_dates(self): ===================== Set initial dates for all main level objects:: >>> sim._ctrl.use_data_date = True >>> sim._set_dates() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2005...7...2..., ...2004...7...2..., ...2015...7...2...], dtype=object), set_init_date=True) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2005., 2004., 2015.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 7., 7., 7.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 2., 2., 2.])) >>> sim.data.get_date.mock_returns = np.array([ ... dt.date(1999,1,1), ... 0, ... dt.date(2005,1,1)], dtype=dt.date) >>> sim._set_dates() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.get_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...1999...1...1..., ...2000...1...1..., ...2005...1...1...], dtype=object), set_init_date=True) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 1999., 2000., 2005.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 1., 1., 1.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 1., 1., 1.])) >>> sim._ctrl.use_data_date = False >>> sim._ctrl.use_today = False >>> sim._set_dates() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_tind(1, 0) Called Handler.set_date( array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), array([...2000...1...1..., ...2000...1...1..., ...2000...1...1...], dtype=object), set_init_date=True) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 3, array([ 2000., 2000., 2000.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 4, array([ 1., 1., 1.])) Called Handler.set_value( 1, array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 2, 0, 0]]), 5, array([ 1., 1., 1.])) def add_error(self, errorstr, level, obj, tind=None): ===================================================== Log error message and update error counters. Add a general error message :: >>> sim.add_error("This is a general error", None, None) Called Logger.log_message('test-log', 'ERROR', 'This is a general error') def add_warning(self, warningstr, level, obj, tind=None): ========================================================= Log warning message. Add a general warning message :: >>> sim.add_warning("This is a general warning", None, None) Called Logger.log_message('test-log', 'WARNING', 'This is a general warning') def _add2log(self, msg, level, obj, tind, mtype): ========================================================= Add messages to log. Messages can be general or object-specific, in which case object indice(s) must be given as an input parameter. Target index is an optional parameter. >>> tind = np.array([[1, 2, 0, 0, 0], ... [0, 0, 1, 0, 0], ... [0, 0, 2, 0, 0]], dtype=int) >>> sim.task = Mock('Task') >>> sim.task.path = 'path/of/this/task' Add a general message :: >>> sim._add2log("This is a general message", None, None, 'TEST') Called Logger.log_message( 'test-log', 'TEST', 'SIMULATION STEP 1, TASK: path/of/this/task, This is a general message') Add a message for a single object at simulation main level :: >>> sim.level = sim.main_level = 1 >>> sim.data.get_id.mock_returns = [(u'3', u'3')] >>> sim.data.get_date.mock_returns = [dt.date(2003,3,3)] >>> etind = np.array([[0, 0, 2, 0, 0]], dtype=int) >>> sim._add2log("This is a message for a single object", 1, etind, 'TEST') Called Handler.get_id(1, array([[0, 0, 2, 0, 0]])) Called Handler.get_date(array([[0, 0, 2, 0, 0]])) Called Lexicon.get_level_name(1) Called Logger.log_message( 'test-log', 'TEST', u"TASK: path/of/this/task, DATE: 2003-03-03, SIMULATION UNIT: '3', ITERATION: 0, BRANCH: 0, OBJECT: comp_unit '3': This is a message for a single object", u'3') Add a message for multiple objects at simulation main level :: >>> sim.level = sim.main_level = 1 >>> sim.data.get_id.mock_returns = [(u'3', u'3'), (u'7', u'7')] >>> sim.data.get_date.mock_returns = [dt.date(2003,3,3),dt.date(2007,7,7)] >>> etind = np.array([[1, 2, 0, 0, 0], ... [0, 0, 2, 0, 0]], dtype=int) >>> sim._add2log("This is a message for a single object", 1, etind, 'TEST') Called Handler.get_id(1, array([[1, 2, 0, 0, 0], [0, 0, 2, 0, 0]])) Called Handler.get_date(array([[1, 2, 0, 0, 0], [0, 0, 2, 0, 0]])) Called Lexicon.get_level_name(1) Called Logger.log_message( 'test-log', 'TEST', u"TASK: path/of/this/task, DATE: 2007-07-07, SIMULATION UNIT: '7', ITERATION: 0, BRANCH: 0, OBJECT: comp_unit '7': This is a message for a single object", u'7') Called Logger.log_message( 'test-log', 'TEST', u"TASK: path/of/this/task, DATE: 2003-03-03, SIMULATION UNIT: '3', ITERATION: 1, BRANCH: 2, OBJECT: comp_unit '3': This is a message for a single object", u'3') Add a message for a single object on simulation main level's child level :: >>> sim.level = 3 >>> sim.data.get_id = Mock('get_id') >>> sim.data.get_id.mock_returns_iter = iter([[(u'4-2-11', u'4-2-11')], ... [(u'4', u'4')]]) >>> sim.data.get_parent.mock_returns = \ ... np.array([[1,3,0,0,0]], dtype=int), None >>> sim.lexicon.get_level_name.mock_returns = 'tree' >>> sim.data.get_date.mock_returns = [dt.date(2004,4,4)] >>> etind = np.array([[1, 2, 0, 0, 0]], dtype=int) >>> sim._add2log("This is a message for a single object", 3, etind, 'TEST') Called Handler.get_parent(3, array([[1, 2, 0, 0, 0]]), 1) Called get_id(3, array([[1, 2, 0, 0, 0]])) Called Handler.get_date(array([[1, 3, 0, 0, 0]])) Called get_id(1, array([[1, 3, 0, 0, 0]])) Called Lexicon.get_level_name(3) Called Logger.log_message( 'test-log', 'TEST', u"TASK: path/of/this/task, DATE: 2004-04-04, SIMULATION UNIT: '4', ITERATION: 1, BRANCH: 2, OBJECT: tree '4-2-11': This is a message for a single object", u'4') def _add_opres_to_db(self): =========================== Add the queued operation results to operation database.:: >>> import numpy >>> sim._opres_queue = [('simulated', numpy.array([[0, 0, 0, 0, 0]]), ... (0, 0, 'comp_unit', 's1'), 'fop1', ... [([{'cash_flow': -100.0}], None)], 'planting', 'silviculture', ... 'notes', ['material', 'another material'])] >>> sim._add_opres_to_db(data_db) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_date(array([[0, 0, 0, 0, 0]])) Called DataDB.add_opres( 'comp_unit', [{...}]) Test adding operation results with delay:: >>> import numpy >>> sim._opres_queue = [('simulated', numpy.array([[0, 0, 0, 0, 0]]), ... (0, 0, 'comp_unit', 's1'), 'fop1', [([{'cash_flow': -100.0}], 5)], ... 'planting', 'silviculture', 'notes', ['material', ... 'another material'])] >>> sim._add_opres_to_db(data_db) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE Called Handler.get_date(array([[0, 0, 0, 0, 0]])) Called DataDB.add_opres( 'comp_unit', [{...}]) def _check_timestep_saving(self, step): ======================================= Check if data from current time step should be stored to result db.:: >>> sim._blocked_from_db set([]) >>> sim.timespan.save_steps_to_db = 'all' >>> sim._check_timestep_saving(1) True >>> sim.timespan.save_steps_to_db = 'none' >>> sim._check_timestep_saving(1) False >>> sim.timespan.save_steps_to_db = 'last' >>> sim._end_step 10 >>> sim._last_step_objs = set([(0, 0, 0), (0, 0, 1), (0, 0, 2)]) >>> sim._check_timestep_saving(1) Called Handler.get_tind(1, None) True >>> sim._end_step = 3 >>> sim._last_step_objs = None >>> sim._check_timestep_saving(1) False >>> sim._check_timestep_saving(2) True def _temporary_activation(self, block_active): ============================================== Activate just blocked objects temporarily. This can be in two cases:: 1. only last time step should be stored, and some of the objects have just reached their last time step (due to end date or stop condition, but some of the objects are still simulated 2. all time steps should be stored, but some of the units are blocked from db already during first time step because their date is past the time span end date Parameters :: block_active -- indicates whether currently active objects should be Set the blocked and last step objects and activate temporarily without blockin the active objects :: >>> sim.data.get_tind.mock_returns = numpy.array([[0,0,4,0,0], ... [0,0,5,0,0], ... [0,0,6,0,0]], dtype=int) >>> sim._blocked_for_good = set([(0,0,0), (0,0,1), (0,0,2)]) >>> sim._blocked_from_db = set([(0,0,2), (0,0,3)]) >>> sim._last_step_objs = set([(0,0,4), (0,0,5)]) >>> sim._temporary_activation(False) >>> sim._blocked_from_db set([(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3)]) >>> sim._temporarily_activated set([(0, 0, 2), (0, 0, 3)]) Set the blocked and last step objects and activate temporarily, and also block the active objects :: >>> sim.data.get_tind.mock_returns = numpy.array([[0,0,4,0,0], ... [0,0,5,0,0], ... [0,0,6,0,0]], ... dtype=int), None >>> sim._blocked_for_good = set([(0,0,0), (0,0,1), (0,0,2)]) >>> sim._blocked_from_db = set([(0,0,2), (0,0,3), (0,0,4)]) >>> sim._last_step_objs = set([(0,0,3), (0,0,4)]) >>> sim._temporary_activation(True) Called Handler.get_tind(1, None) >>> sim._blocked_from_db set([(0, 0, 5), (0, 0, 0), (0, 0, 2), (0, 0, 4), (0, 0, 6), (0, 0, 1)]) >>> sim._temporarily_activated set([(0, 0, 2), (0, 0, 3), (0, 0, 4)]) def _revert_blocks(self): ========================= Revert the blocks made in '_check_timestep_storing' method.:: >>> sim._revert_blocks() >>> sim._last_step_objs set([(0, 0, 3), (0, 0, 4)]) >>> sim._blocked_from_db set([(0, 0, 2), (0, 0, 3), (0, 0, 4)]) >>> sim._temporarily_activated def _sub_year_step(self): ========================= Check if the current time span has time steps less than one year >>> sim._sub_year_step() False >>> sim.timespan.unit = 'month' >>> sim.timespan.time_step = 60 >>> sim._sub_year_step() False >>> sim.timespan.time_step = 12 >>> sim._sub_year_step() False >>> sim.timespan.time_step = 3 >>> sim._sub_year_step() True