The model chains define how the models are applied to the data to get the desired results out of the simulation. Each simulation usually consists of several model chains which are applied to the data in the order defined in the simulation XML document (Simulation).
An example of the document contents is given below, for a comprehensive description of all the possible content options see the schema document. Data continuation and abbreviated content expressed as …:
The root level tag contains a reference to the schema document which is used to validate the content of the XML document:
<model_chains xmlns="http://www.simo-project.org/simo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.simo-project.org/simo ../../schemas/model_chain.xsd">
Model chain content is grouped into chain groups. Their function is just to clarify the content of the document. The actual simulation logic is contained in the model chains (model_chain). Each model chain is associated to a data level (evaluate_at); i.e., the tasks of the chain are only applied to the data objects of that data level:
…
<chain_group name="Biomass of growing stock, dry weight in kilograms">
<model_chain name="calculate biomass of tree" evaluate_at="tree">
Each model chain consists of a set of tasks. The name of the task is used if warning or error messages need to generated. The execution of a task can depend on a condition; in the example the task “calculate if trees exist” is executed if the stratum level attribute seedling_below13 value equals (eq) 0:
…
<task name="calculate if trees exist">
<condition>stratum:seedling_below13 eq 0</condition>
Each task may have sub tasks; here the “calculate if trees exist” task has a sub task “Calculate biomass of a tree”. If a task is not divided into further sub tasks, it has a model associated with it; here Biomass_tree_JKK. The name of the model must match the one defined in the prediction model document (Prediction model) if its type is prediction (for other options see below):
…
<task name="Calculate biomass of a tree">
<model>
<name>Biomass_tree_JKK</name>
<prediction/>
</model>
</task>
</task>
</model_chain>
</chain_group>
</model_chains>
Each model chain can also have number of branching_groups, which are used in generating so-called branches, or, alternative development paths. Each branching_group consists of a number of branch_tasks. A branch_task has attribute ‘branching_operations’ which contains operations that actually create a new branch.
OBS! Notice that even if you have separate branching groups for thinnings and clearcuts, the branching group name attribute should be equal for the separate groups. Such as “Normal harvest” as in the example below.
A branching group element for regeneration harvests (clearcut & seedtree_position)
…
<branching_group name="Normal harvest">
<branch_task branching_operations="seedtree_position;clearcut"
name="Clearcut or seedtree cut">
A branching group element for thinnings (thinning & seedtree cut)
…
<branching_group name="Normal harvest">
<branch_task branching_operations="first_thinning;thinning"
name="First thinning or normal thinning">
Notice that the branching group name, “Normal harvest”, is the same for the both branching groups.
Each branch task has normal condition element, number of normal tasks and a branch_conditions -element, which includes a number of normal condition elements. Each of these branch_condition elements can create a new branch if the condition is fulfilled:
…
<branch_conditions>
<condition name="Normal clearcut">
comp_unit:passed_regen_limit gt 0</condition>
<condition name="Delayed clearcut, 5 years">
comp_unit:passed_regen_limit gt 5</condition>
<condition name="Delayed clearcut, 10 years">
comp_unit:passed_regen_limit gt 10</condition>
</branch_conditions>
<condition>comp_unit:MAIN_GROUP eq 1 and
comp_unit:REGENERABLE eq 1</condition>
<task name="Clearcut">
…
The allowed values for operators used in conditions are:
Data attribute related:
Forestry operation related:
The condition consists of expressions that may be nested. Each expression has two operands that are compared with an operator (see above).
There are several possible two-operand combinations:
The most common is the one comparing an attribute value to a fixed value (see above).
The attribute value can also be compared to another attribute value. Here the D_gM attribute from comp_unit level should have at least equal value to the regen_dgm attribute value from the comp_unit level:
<condition>comp_unit:D_gM ge comp_unit:regen_dgm</condition>
A set of allowed values can also be given for an attribute. In this case the operator used is always ìn. Here the SP attribute from stratum level must have one of the values 3, 4, 5, 6, 7, 9:
<condition>stratum:SP in [3, 4, 5, 6, 7, 9]</condition>
The conditions can also test for operation execution. Here more than 10 years must have passed since the last thinning:
<condition>comp_unit:thinning since_gt 10</condition>
As for the data attributes, the operation execution can be compared to a attribute value. Here more years than defined by the simulation level attribute REMOVE_SEEDTREES_YEARS_SINCE_REGEN_CUT_PINE must have passed since the latest comp_unit operation seedtree_position. Note that if an operation has never been done, the since_eq, since_gt and since_lt will evaluate true:
<condition>comp_unit:seedtree_position
since_gt
simulation:REMOVE_SEEDTREES_YEARS_SINCE_REGEN_CUT_PINE"
</condition>
The condition can also test for existence of a data level in the data:
<condition>stratum exists</condition>
<condition>stratum not exists</condition>
Finally, it’s possible to construct a more complicated condition by using the and and or operators and grouping the expressions with parenthesis:
((comp_unit:AGE gt 1.0 and comp_unit:SC le 4.0)
or
stratum:SP in [1.0, 2.0, 3.0])
and
((comp_unit:thinning since_gt 10
or comp_unit:thinning since_gt comp_unit:past_thinning)
or stratum not exists)
Six different types of models can be used in model chains.
<model>
<name>Development_class_JKK</name>
<prediction/>
</model>
When aggregation operand variable and/or weight have default attributes, missing (NaN) values are substituted with the default values before passing the values to the actual aggregation model implementation.
Aggregation model:
<model>
<name>sum</name>
<aggregation>
<target>N</target>
<operands>
<operand>
<variable default="1">N</variable>
<weight default="0">BA</weight>
<level>stratum</level>
</operand>
</operands>
</aggregation>
</model>
Aggregation model targets and operands can be “vectorised”, i.e. multiple variables or values instead of single variable or value, separated with whitespace (i.e. a single space). Note that target vector and operand vectors (value, variable and weight) must contain equal number of items, and the used aggregation model must have vector implementation:
<model>
<name>assign_value</name>
<aggregation>
<target>N BA V D_gM H_gM</target>
<operands>
<operand>
<value>0 0 0 0 0</value>
</operand>
</operands>
</aggregation>
</model>
Conditions can also be used in aggregation models to limit the data that is being passed to the aggregation model. In these conditions a special data level name ‘self’ must be used to refer to the target model chain evaluation level objects. E.g. the aggregation model below computes the sum of the products of ‘ga’ and ‘n’ variables for trees that have bigger diameter (‘tree:d’) than the tree (‘self:d’) for which the sum of products is computed for:
<task
name="Calculate relative density factor of trees larger than the
object tree">
<model>
<name>sum_products</name>
<aggregation>
<target>RDF_L</target>
<through_level>comp_unit</through_level>
<operands>
<operand>
<variable>ga</variable>
<level>tree</level>
</operand>
<operand>
<variable>n</variable>
<level>tree</level>
</operand>
</operands>
<condition>tree:d gt self:d</condition>
</aggregation>
</model>
</task>
Similarly, this ‘comp_unit’ level task computes the ‘tree’ level weighted average for only those threes that have a bigger diameter than the ‘comp_unit’ level mean diameter (self:D_gM):
<task name="Calculate mean crown ratio for dominant trees">
<model>
<name>w_average</name>
<aggregation>
<target>CR_dom</target>
<operands>
<operand>
<variable>cr</variable>
<weight>n</weight>
<level>tree</level>
</operand>
</operands>
<condition>tree:d gt self:D_gM</condition>
</aggregation>
</model>
</task>
erase_memory – will clear the prediction model memory for all objects for which the operation model is executed if set to true. db_names – optional name and group to be saved to result database (as opposed to the name and group of the operation) notes – optional notes on the operation, will be saved to the result database materials – optional materials needed to perform the operation, will be saved to the result database
<model>
<name>clearcut</name>
<operation>
<simulation_effects>
<erase_memory>false</erase_memory>
</simulation_effects>
<db_names>
<name>clearcut</name>
<group>final_harvest_artificial_regeneration</group>
</db_names>
<notes>This is a clearcut</notes>
<materials>
<material>Fuel</material>
</materials>
<parameters>
<parameter>
<name>LOG_REDUCTION_PINE</name>
<value>10</value>
</parameter>
<parameter>
<name>LOG_REDUCTION_SPRUCE</name>
<value>8</value>
</parameter>
<parameter>
<name>LOG_REDUCTION_OTHER</name>
<value>15</value>
</parameter>
</parameters>
<cash_flow_table>timber_prices</cash_flow_table>
</operation>
</model>
<model desc="Delete all objects from level stratum">
<name>remove_objects_from_child_level</name>
<management>
<parameters>
<parameter>
<level>stratum</level>
</parameter>
</parameters>
</management>
</model>
<model>
<name>regeneration_limits</name>
<parameter_table/>
</model>
<model>
<name>dem</name>
<geo_table>
<all_vars>true</all_vars>
</geo_table>
</model>