.. _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