Result models

From Heureka Wiki
Jump to navigation Jump to search

Implementing a Result Model

A result model is implemented as a class that is depending on:

  1. Treatment Unit
  2. Period (optional)
  3. Before or after treatment in the period (optional)
  4. Other results (optional)

The class is given the attribute Slu.Heureka.DomainLayer.Forest.TreatmentUnitResult. In the attribute it is specified which of the above parameters that are required by the model (the attribute also specifices more information about the result model, see code for more details).

The class must also have a constructor with the required parameters, in the same order as above. When a new instance of the class is created, the results of the model should be calculated.

All properties of the class will be exposed as result variables, unless the attribute Browsable is set to false.

Each property must be a simple type (nullable simple types are allowed), or a SpeciesCollection. Note that all simple types not have been used, so simple types other than int, double, bool, and int-based enums should be tested carefully.

On each property the DisplayName attribute and the Slu.Heureka.DomainLayer.Forest.Unit attribute may be given. The former is the name that will be presented to the user for the property, and the latter gives the user extra information about the unit of the attribute.

Once the model is implemented as above, the result variables will be available in maps, diagrams, tables, optimization models, and forest domains.

Different types of result models

There are several different types of result models:

Before/After result
Results that might be changed when a treatment occurs, e.g. volume, biomass
Treatment result
Somewhat misleading term for results that are the product by a treatment (e.g. cut volume), or that are not changed in the same period due to treatments (e.g. growth, carbon and nitrogen)
Single result
Results that are independent of period, that spans an entire alternative (e.g. net present value)
Generated result
Most results are generated from a simulation, but some results (e.g. habitat value) cannot be generated in a simulation, such non-generated results are created from an entire plan

Advanced result model implementation considerations

All result model classes should implement IClonable and return a deep copy of the result when cloned.

Results that depend on year or their relative position among other results (e.g. CarbonAndNitrogenData) must implement the IRecalculatableResult interface. The reason for this is that for efficiency reasons results may be copied from one generation to another (e.g. if generation 3 of a TreatmentUnit should be identical to generation 2). The interface is implemented as follows:

SetDirty(int period, double year)
Called when the result is copied from one generation to another
IsDirty
Indicates that the result is dirty and needs recalculation to become valid
Update(IList<Result> results)
Called when the result should be updated
Clean()
Called when the result no longer needs to be recalculated (allows cleanup of intermediate results)

Getting results in code

The results of each result model is managed by the Result class, which acts as a container of result model objects, and can be accessed via a TreatmentUnit:

GetResult(int period)
Gets the results in a given period changes)
GetResults()
Gets all results up to current period
CopyResults(IList<Type> resultTypes)
Gets a deep copy of all results up to current period, with all result models of the given types calculated.

Note that results retrieved via the first two methods might later be changed if the state of the TreatmentUnit changes. The values from a given result model can be retrieved on demand when the result(s) has been retrieved. Results retrieved via the last method are a copy and thus will not be changed, and the result models must be specified beforehand, values from result models not given in the call cannot be retrieved at a later time.

Once a Result object has been retrieved, it is possible to get result model objects from it:

ContainsBefore(Type t), ContainsAfter(Type t), ContainsTreatment(Type t)
Checks if the given result model type exists in the result
Before(Type t), After(Type t), Treatment(Type t)
Gets the result model objects of the given type (note that several objects may be retrieved)
BeforeAndAfterSame
Returns a value indicating that values before treatment are identical to values after treatment (e.g. no treatment has been performed in the period the result belongs to)

The inner workings of the result class