.. _operationmodel-py:
#################
operationmodel.py
#################
::
>>> from simo.builder.modelbase.operationmodel import OperationModel
>>> from minimock import Mock
>>> from lxml import etree
>>> xml = u'''
...
... thinning
...
...
... harvest.py
... python
... model
... on
...
...
... ...
...
...
... comp_unit
...
...
... D_gM
...
... 0
... 40
...
...
...
...
...
...
...
... STEM_DIVISOR
... simulation
...
...
...
...
... target_density
... false
...
... 10 20 30
...
...
...
... required_param
... false
...
...
... hupi_param
... True
...
...
...
... thinning_preference_order
...
...
... AREA
... comp_unit
...
...
...
...
...
...
... Volume
...
...
... SP
... stratum
...
...
...
... assortment
...
...
...
...
...
... C_flow
...
...
...
...
...
... '''
>>> 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': , 'order': , 'limits': }
- 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] # doctest: +ELLIPSIS
(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 # doctest: +ELLIPSIS
{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 # doctest: +NORMALIZE_WHITESPACE
[('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'''
...
... false
...
...
... model_db_name
... model_db_group
...
...
...
... stratum
... iBA
...
...
...
... 0
... 5
...
... 1.25
...
...
...
...
... stratum
...
...
... target_density
... 0.5
...
...
... track_width
... 4
...
...
...
...
... thinning_preference_order
... thinning_preference_order
...
...
... dummy
... dummy_table
...
...
...
... timber_prices
...
... '''
>>> 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 # doctest: +ELLIPSIS
[]
>>> omp.cash_flow_model
>>> omp.parameter_tables # doctest: +ELLIPSIS
[]
>>> omp.memory_level
2
>>> errs = list(task.validator.errors)
>>> errs.sort()
>>> errs # doctest: +NORMALIZE_WHITESPACE
["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) # doctest: +NORMALIZE_WHITESPACE
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