Table Of Contents

Previous topic

modelbase.py

Next topic

parametertable.py

This Page

operationmodel.py

>>> from simo.builder.modelbase.operationmodel import OperationModel
>>> from minimock import Mock
>>> from lxml import etree
>>> xml = u'''<operation_group name='testgroup'>
...             <operation>
...             <name>thinning</name>
...             <type>
...                 <model>
...                     <implemented_at>harvest.py</implemented_at>
...                     <implemented_in>python</implemented_in>
...                     <cash_flow_handler>model</cash_flow_handler>
...                     <interaction>on</interaction>
...                 </model>
...             </type>
...             <description>...</description>
...             <data>
...                 <group>
...                     <level>comp_unit</level>
...                     <variables>
...                         <variable>
...                             <name>D_gM</name>
...                             <limits>
...                                <lower_limit>0</lower_limit>
...                                <upper_limit>40</upper_limit>
...                             </limits>
...                         </variable>
...                     </variables>
...                 </group>
...             </data>
...             <variables>
...                 <variable>
...                     <name>STEM_DIVISOR</name>
...                     <level>simulation</level>
...                 </variable>
...             </variables>
...             <parameters>
...                 <parameter>
...                     <name>target_density</name>
...                     <optional>false</optional>
...                     <limits>
...                        <enum>10 20 30</enum>
...                     </limits>
...                 </parameter>
...                 <parameter>
...                     <name>required_param</name>
...                     <optional>false</optional>
...                 </parameter>
...                 <parameter>
...                     <name>hupi_param</name>
...                     <optional>True</optional>
...                 </parameter>
...             </parameters>
...             <parameter_tables>
...                <parameter_table>thinning_preference_order</parameter_table>
...             </parameter_tables>
...             <operation_result_weight>
...                 <name>AREA</name>
...                 <level>comp_unit</level>
...             </operation_result_weight>
...             <results>
...                 <type>
...                     <operation_result/>
...                     <variables>
...                         <variable>
...                             <name>Volume</name>
...                             <classifiers>
...                                 <classifier>
...                                     <variable>SP</variable>
...                                     <level>stratum</level>
...                                 </classifier>
...                                 <classifier>
...                                     <cashflow_classifier>
...                                         <variable>assortment</variable>
...                                     </cashflow_classifier>
...                                 </classifier>
...                             </classifiers>
...                         </variable>
...                         <variable type="date_array">
...                             <name>C_flow</name>
...                         </variable>
...                     </variables>
...                 </type>
...             </results>
...         </operation>
...     </operation_group>'''
>>> dummynotextlevel = Mock('Level')
>>> dummynotextlevel.textual = []
>>> dummytextlevel = Mock('Level')
>>> dummytextlevel.textual = ['stand_number']
>>> dummylexicon = Mock('Lexicon')
>>> dummylexicon.get_level_name.mock_returns = 'comp_unit'
>>> dummylexicon.level_ind = {'comp_unit': 1, 'stratum': 2, 'tree': 3}
>>> dummylexicon.levels = {'simulation': dummynotextlevel,
...                   'comp_unit': dummytextlevel,
...                   'stratum': dummynotextlevel}
>>> class Validator:
...     lexicon = dummylexicon
...     def elem_name(self, text):
...         return text
...     def variable_ind(self, level, variable, active=False):
...         return (1,1)
...     def level_ind(self, level):
...         return 1
...     def add_model(self, mtype, mname):
...         return 15
>>> elem = etree.fromstring(xml)

class OperationModel(Model):

Class for operation model definitions

Properties:

  • type: get model type as string
  • name: get model name as string
  • language: get model implementation language as string
  • dirs: get model library directories as a list of strings
  • function: get model function object
  • library: get model library object
  • wrapper: get model library wrapper object

Attributes:

  • n_vars: number of input variables
  • vars: input variables in a dictionary: level as the key and value is a dictionary with the structure {‘index’: <variable indices in a list>, ‘order’: <variable order in a list>, ‘limits’: <variable limits in a list>}
  • n_params: number of input parameters
  • params: dictionary of parameters keyed by parameter name, valued by tuples of (optional, parameter limits)
  • optype: operation type as string
  • operation_result_weight: operation result variable indice: (level, variable)
  • data_vars: input data as dictionary, levels as keys, lists of variable indices as values
  • data_limits: input data limits
  • cash_flow_handler: string, either ‘model’ or ‘simulator’
  • interactive: True or False, if interactive, model can affect data values, non-interactive models can only produce operation results.
  • parameter_tables: list of parameter table names
  • result_type: ‘data’ or ‘operation_result’
  • result_level: operation result target level
  • result_target: ‘existing’ or ‘new’
  • result_variables: list of result variable tuples: (variable, classifier key)
  • result_classifiers: dictionary, where key: classifier key, value: list of classifier definitions

def __init__(self, ns, elem, validator, dirs, group):

Construct operation model object from XML element:

>>> op = OperationModel('', elem[0], Validator(), ['dummydir'], \
...                     'testgroup')
>>> op.name
'thinning'
>>> op.group
'testgroup'
>>> op.language
'python'
>>> op._lib
'harvest.py'
>>> op.vars
{1: {'index': array([1]), 'order': [0], 'limits': [None]}}
>>> ind = op.param_names.index('target_density')
>>> op.param_defs[ind] 
(False, <...Limit object...>)
>>> ind = op.param_names.index('required_param')
>>> op.param_defs[ind]
(False, None)
>>> ind = op.param_names.index('hupi_param')
>>> op.param_defs[ind]
(True, None)
>>> op.n_params
3
>>> ind = op.param_names.index('target_density')
>>> l = op.param_defs[ind][1]
>>> l.enum
[10.0, 20.0, 30.0]
>>> l.lower
>>> op.operation_result_weight
(1, 1)
>>> op.data_vars
{1: [1]}
>>> op.data_limits 
{1: [<...Limit object...>]}
>>> l = op.data_limits[1][0]
>>> l.lower
0.0
>>> l.upper
40.0
>>> op.cash_flow_handler
'model'
>>> op.interactive
True
>>> op.parameter_tables
['thinning_preference_order']
>>> op.result_type
['operation_result']
>>> op.result_level
>>> op.result_target
>>> op.result_variables 
[('operation_result', 'Volume', ('SP', 'assortment'), 'scalar', True),
 ('operation_result', 'C_flow', None, 'date_array', True)]
>>> op.result_classifiers.keys()
[('SP', 'assortment')]
>>> op.index
15

def _parse_operation(self, ns, elem):

Parse operation model structures

def _parse_data(self, ns, elem):

Parse operation model input data structures

def _parse_param_tables(self, ns, elem):

Parse operation parameter table names

def _parse_weights(self, ns, elem):

Parse operation model result weight variable

def _parse_results(self, ns, elem):

Parse operation model result structures

def _parse_classifiers(self, ns, elem):

Parse operation model result classifiers

class Classifier(object):

Class for operation model result classifiers

Attributes:

  • type
  • variable
  • level

def __init__(self, type, variable, level):

class OperationModelParam(object):

Operation model parameters

Attributes:

  • parameters: operation model parameters in a dictionary, where parameter name is key and parameter value(s) is value
  • long_term: list of effects, effect: {‘variable’: ... , ‘level’:, ... , ‘effect: ...}
  • cash_flow_table: cash flow table implementation
  • cash_flow_model: cash flow model implementation
  • parameter_tables: parameter tables as a list implementations
  • simulation_effects: simulation effects in a dictionary
  • memory_level: memory level indice

def __init__(self, ns, elem, validator, model, cftables, cfmodels, ptables):

Construct operation model parameters:

>>> execfile('builder/modelbase/test/mocktask.py')
>>> xml = u'''<operation>
...   <simulation_effects>
...     <erase_memory>false</erase_memory>
...   </simulation_effects>
...   <db_names>
...      <name>model_db_name</name>
...      <group>model_db_group</group>
...   </db_names>
...   <long_term>
...     <variable_effect>
...       <level>stratum</level>
...       <variable>iBA</variable>
...       <effects>
...         <effect>
...           <time_period>
...             <start>0</start>
...             <end>5</end>
...           </time_period>
...           <factor>1.25</factor>
...         </effect>
...       </effects>
...     </variable_effect>
...   </long_term>
...   <memory_level>stratum</memory_level>
...   <parameters>
...     <parameter>
...       <name>target_density</name>
...       <value>0.5</value>
...     </parameter>
...     <parameter>
...       <name>track_width</name>
...       <value>4</value>
...     </parameter>
...   </parameters>
...   <parameter_tables>
...     <parameter_table>
...       <table_definition_name>thinning_preference_order</table_definition_name>
...       <value_table_name>thinning_preference_order</value_table_name>
...     </parameter_table>
...     <parameter_table>
...       <table_definition_name>dummy</table_definition_name>
...       <value_table_name>dummy_table</value_table_name>
...     </parameter_table>
...   </parameter_tables>
...   <cash_flow_tables>
...     <cash_flow_table>timber_prices</cash_flow_table>
...   </cash_flow_tables>
... </operation>'''
>>> elem = etree.fromstring(xml)
>>> from simo.builder.modelbase.operationmodel import OperationModelParam
>>> cftables = {'timber_prices': Mock('CashFlowTable')}
>>> cftables['timber_prices'].classifier_order = [1]
>>> cftables['timber_prices'].keycount=1
>>> clf = Mock('Classifier')
>>> clf.level = 1
>>> clf.ind = 2
>>> cftables['timber_prices'].classifiers = {1:clf}
>>> cfmodels = {'cf_model': Mock('CashFlowModel')}
>>> ptables = {'thinning_preference_order': Mock('ParameterTable')}
>>> omp = OperationModelParam('', elem, task, op, cftables, cfmodels,
...                           ptables)
>>> omp.simulation_effects
{'force_step': None, 'erase_memory': False}
>>> omp.name
'model_db_name'
>>> omp.group
'model_db_group'
>>> omp.parameters
[0.5, None, None]
>>> omp.long_term
[{'variable': 1, 'effects': [[[0, 5], 1.25]], 'level': 2}]
>>> omp.cash_flow_table 
[<Mock ... CashFlowTable>]
>>> omp.cash_flow_model
>>> omp.parameter_tables 
[<Mock ... ParameterTable>]
>>> omp.memory_level
2
>>> errs = list(task.validator.errors)
>>> errs.sort()
>>> errs 
["Cash flow table key classifier '1' not found on level 'comp_unit'
     for operation model 'thinning', task 'test task'",
 "Non optional parameter 'required_param' is not defined for operation
     model 'thinning', task 'test task'",
 "Parameter 'track_width' is not a valid parameter for operation model
     'thinning', task 'test task'",
 "Parameter table 'dummy' is not valid for operation model 'thinning',
     task 'test task'",
 "Value 0.5 for parameter 'target_density' is not in the accepted value
     list [10.0, 20.0, 30.0] for operation model 'thinning',
     task 'test task'"]

def _parse_params(self, ns, elem):

Parse operation model parameters when there shouldn’t be any

>>> ns = ''
>>> elem = Mock('Elem')
>>> elem.find.mock_returns = None
>>> omp.model = Mock('Model')
>>> omp.model.n_params = 0
>>> omp.model.name = 'test model'
>>> omp._validator = Mock('Validator')
>>> omp._parse_params(ns, elem)
Called Elem.find('parameters')

Parse parameters when there should be two, but there are none

>>> omp.model.n_params = 2
>>> omp._parse_params(ns, elem) 
Called Elem.find('parameters')
Called Validator.add_error(
    "No parameters defined for model 'test model', 2 expected, task 'test
     task'")

def _parse_long_term(self, ns, elem):

Parse operation model long time effects

def _get_cash_flow_table(self, ns, elem):

Get operation model cash flow table

def _get_cash_flow_model(self, ns, elem):

Get operation model cash flow model

def _get_param_tables(self, ns, elem):

Get operation model parameter tables

def _get_sim_effects(self, ns, elem):

Get operation model simulation effects

def _get_mem_level(self, ns, elem):

Get operation model memory level