The ClimIndices.Extension project shows how to extend the UNIMI.ClimIndices component by creating a new index (a new strategy) and by extending one domain class.
The domain class extended is DataClimIndices: the new DataClimIndicesExtension class inherits from the DataClimIndices. The domain class is extended by adding a new property, GDDCustomPeriod, which is the output of the new strategy. Extending the value class requires also a new VarInfo class, in this case DataClimIndicesExtensionVarInfo.
The new component also uses a static class TraceCI.cs, which contains an helper method to use the System.TraceSource class.
The extended strategy differs from a strategy in ClimIndices only because a recast of the DataClimIndices domain class is needed to access the extended property. The code of the extended class of the ClimIndices.Extension project is shown below. In spite of the apparent complexity (the code is much more readable in the Visual Studio IDE), most of the code would be reused to add another strategy.
ExtensionStrategy : IClimIndicesStrategy |
//Author: Ermes Movedi
//Institution:University of Milan
//Author of revision:
//Date first release:01/13/2015
//Date of revision:
using System;
using System.Collections.Generic;
using System.Xml;
using System.Linq;
using CRA.ModelLayer.MetadataTypes;
using CRA.ModelLayer.Core;
using CRA.ModelLayer.Strategy;
using System.Reflection;
using VarInfo = CRA.ModelLayer.Core.VarInfo;
using Preconditions = CRA.ModelLayer.Core.Preconditions;
using UNIMI.ClimIndices.Interfaces;
//To make this project compile please add the reference to assembly: UNIMI.ClimIndices.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
//To make this project compile please add the reference to assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//To make this project compile please add the reference to assembly: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//To make this project compile please add the reference to assembly: CRA.ModelLayer, Version=1.0.5212.29139, Culture=neutral, PublicKeyToken=null
//To make this project compile please add the reference to assembly: System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//To make this project compile please add the reference to assembly: System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a;
namespace ClimIndices.Extension
{
/// <summary>
///Class ExtensionStrategy
/// Example for extending the component: it calculates the growing degree days between two days (parameters).
/// </summary>
public class ExtensionStrategy : IClimIndicesStrategy
{
#region Constructor
public ExtensionStrategy()
{
ModellingOptions mo0_0 = new ModellingOptions();
//Parameters
List<VarInfo> _parameters0_0 = new List<VarInfo>();
VarInfo v1 = new VarInfo();
v1.DefaultValue = 5.6;
v1.Description = "Temperature base for growth";
v1.Id = 0;
v1.MaxValue = 10;
v1.MinValue = 0;
v1.Name = "TemperatureBaseForGrowth";
v1.Size = 1;
v1.Units = "C°";
v1.URL = "";
v1.VarType = CRA.ModelLayer.Core.VarInfo.Type.STATE;
v1.ValueType = VarInfoValueTypes.GetInstanceForName("Double");
_parameters0_0.Add(v1);
VarInfo v2 = new VarInfo();
v2.DefaultValue = 129;
v2.Description = "Start date";
v2.Id = 0;
v2.MaxValue = 150;
v2.MinValue = 1;
v2.Name = "StartDate";
v2.Size = 1;
v2.Units = "day";
v2.URL = "";
v2.VarType = CRA.ModelLayer.Core.VarInfo.Type.STATE;
v2.ValueType = VarInfoValueTypes.GetInstanceForName("Integer");
_parameters0_0.Add(v2);
VarInfo v3 = new VarInfo();
v3.DefaultValue = 225;
v3.Description = "End date";
v3.Id = 0;
v3.MaxValue = 365;
v3.MinValue = 151;
v3.Name = "EndDate";
v3.Size = 1;
v3.Units = "day";
v3.URL = "";
v3.VarType = CRA.ModelLayer.Core.VarInfo.Type.STATE;
v3.ValueType = VarInfoValueTypes.GetInstanceForName("Integer");
_parameters0_0.Add(v3);
mo0_0.Parameters = _parameters0_0;
//Inputs
List<PropertyDescription> _inputs0_0 = new List<PropertyDescription>();
PropertyDescription pd1 = new PropertyDescription();
pd1.DomainClassType = typeof(UNIMI.ClimIndices.Interfaces.DataWeather);
pd1.PropertyName = "AirTemperatureMaximum";
pd1.PropertyType = ((UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMaximum)).ValueType.TypeForCurrentValue;
pd1.PropertyVarInfo = (UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMaximum);
_inputs0_0.Add(pd1);
PropertyDescription pd2 = new PropertyDescription();
pd2.DomainClassType = typeof(UNIMI.ClimIndices.Interfaces.DataWeather);
pd2.PropertyName = "AirTemperatureMinimum";
pd2.PropertyType = ((UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMinimum)).ValueType.TypeForCurrentValue;
pd2.PropertyVarInfo = (UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMinimum);
_inputs0_0.Add(pd2);
mo0_0.Inputs = _inputs0_0;
//Outputs
PropertyDescription pd3 = new PropertyDescription();
pd3.DomainClassType = typeof(ClimIndices.Extension.DataClimIndicesExtended);
pd3.PropertyName = "GDDCustomPeriod";
_inputs0_0.Add(pd3);
mo0_0.Inputs = _inputs0_0;
List<PropertyDescription> _outputs0_0 = new List<PropertyDescription>();
mo0_0.Outputs = _outputs0_0;
//Associated strategies
List<string> lAssStrat0_0 = new List<string>();
mo0_0.AssociatedStrategies = lAssStrat0_0;
//Adding the modeling options to the modeling options manager
_modellingOptionsManager = new ModellingOptionsManager(mo0_0);
SetStaticParametersVarInfoDefinitions();
SetPublisherData();
}
#endregion
#region Implementation of IAnnotatable
/// <summary>
/// Description of the model
/// </summary>
public string Description
{
get { return "Example for extending the component: it calculates the growing degree days between two days (parameters)."; }
}
/// <summary>
/// URL to access the description of the model
/// </summary>
public string URL
{
get { return "http://biomamodelling.org"; }
}
#endregion
#region Implementation of IStrategy
/// <summary>
/// Domain of the model.
/// </summary>
public string Domain
{
get { return "Weather"; }
}
/// <summary>
/// Type of the model.
/// </summary>
public string ModelType
{
get { return "ClimIndices"; }
}
/// <summary>
/// Declare if the strategy is a ContextStrategy, that is, it contains logic to select a strategy at run time.
/// </summary>
public bool IsContext
{
get { return false; }
}
/// <summary>
/// Timestep to be used with this strategy
/// </summary>
public IList<int> TimeStep
{
get
{
IList<int> ts = new List<int>();
return ts;
}
}
#region Publisher Data
private PublisherData _pd;
private void SetPublisherData()
{
// Set publishers' data
_pd = new CRA.ModelLayer.MetadataTypes.PublisherData();
_pd.Add("Creator", "errmes.movedi");
_pd.Add("Date", "01/13/2015");
_pd.Add("Publisher", "University of Milan");
}
public PublisherData PublisherData
{
get { return _pd; }
}
#endregion
#region ModellingOptionsManager
private ModellingOptionsManager _modellingOptionsManager;
public ModellingOptionsManager ModellingOptionsManager
{
get { return _modellingOptionsManager; }
}
#endregion
/// <summary>
/// Return the types of the domain classes used by the strategy
/// </summary>
/// <returns></returns>
public IEnumerable<Type> GetStrategyDomainClassesTypes()
{
return new List<Type>() { typeof(UNIMI.ClimIndices.Interfaces.DataWeather), typeof(UNIMI.ClimIndices.Interfaces.UnivariateDataWeather), typeof(UNIMI.ClimIndices.Interfaces.DataClimIndices) };
}
#endregion
#region Instances of the parameters
// Getter and setters for the value of the parameters of the strategy. The actual parameters are stored into the ModelingOptionsManager of the strategy.
public double TemperatureBaseForGrowth
{
get
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("TemperatureBaseForGrowth");
if (vi != null && vi.CurrentValue != null) return (double)vi.CurrentValue;
else throw new Exception("Parameter 'TemperatureBaseForGrowth' not found (or found null) in strategy 'ExtensionStrategy'");
}
set
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("TemperatureBaseForGrowth");
if (vi != null) vi.CurrentValue = value;
else throw new Exception("Parameter 'TemperatureBaseForGrowth' not found in strategy 'ExtensionStrategy'");
}
}
public int StartDate
{
get
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("StartDate");
if (vi != null && vi.CurrentValue != null) return (int)vi.CurrentValue;
else throw new Exception("Parameter 'StartDate' not found (or found null) in strategy 'ExtensionStrategy'");
}
set
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("StartDate");
if (vi != null) vi.CurrentValue = value;
else throw new Exception("Parameter 'StartDate' not found in strategy 'ExtensionStrategy'");
}
}
public int EndDate
{
get
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("EndDate");
if (vi != null && vi.CurrentValue != null) return (int)vi.CurrentValue;
else throw new Exception("Parameter 'EndDate' not found (or found null) in strategy 'ExtensionStrategy'");
}
set
{
VarInfo vi = _modellingOptionsManager.GetParameterByName("EndDate");
if (vi != null) vi.CurrentValue = value;
else throw new Exception("Parameter 'EndDate' not found in strategy 'ExtensionStrategy'");
}
}
// Getter and setters for the value of the parameters of a composite strategy
#endregion
#region Parameters initialization method
/// <summary>
/// Set parameter(s) current values to the default value
/// </summary>
public void SetParametersDefaultValue()
{
_modellingOptionsManager.SetParametersDefaultValue();
//GENERATED CODE END - PLACE YOUR CUSTOM CODE BELOW - Section5
//Code written below will not be overwritten by a future code generation
//Custom initialization of the parameter. E.g. initialization of the array dimensions of array parameters
//End of custom code. Do not place your custom code below. It will be overwritten by a future code generation.
//PLACE YOUR CUSTOM CODE ABOVE - GENERATED CODE START - Section5
}
#endregion
#region Static parameters VarInfo definition
// Define the properties of the static VarInfo of the parameters
private static void SetStaticParametersVarInfoDefinitions()
{
TemperatureBaseForGrowthVarInfo.Name = "TemperatureBaseForGrowth";
TemperatureBaseForGrowthVarInfo.Description = " Temperature base for growth";
TemperatureBaseForGrowthVarInfo.MaxValue = 10;
TemperatureBaseForGrowthVarInfo.MinValue = 0;
TemperatureBaseForGrowthVarInfo.DefaultValue = 5.6;
TemperatureBaseForGrowthVarInfo.Units = "C°";
TemperatureBaseForGrowthVarInfo.ValueType = CRA.ModelLayer.Core.VarInfoValueTypes.GetInstanceForName("Double");
StartDateVarInfo.Name = "StartDate";
StartDateVarInfo.Description = " Start date";
StartDateVarInfo.MaxValue = 150;
StartDateVarInfo.MinValue = 1;
StartDateVarInfo.DefaultValue = 129;
StartDateVarInfo.Units = "day";
StartDateVarInfo.ValueType = CRA.ModelLayer.Core.VarInfoValueTypes.GetInstanceForName("Integer");
EndDateVarInfo.Name = "EndDate";
EndDateVarInfo.Description = " End date";
EndDateVarInfo.MaxValue = 365;
EndDateVarInfo.MinValue = 151;
EndDateVarInfo.DefaultValue = 225;
EndDateVarInfo.Units = "day";
EndDateVarInfo.ValueType = CRA.ModelLayer.Core.VarInfoValueTypes.GetInstanceForName("Integer");
}
//Parameters static VarInfo list
private static VarInfo _TemperatureBaseForGrowthVarInfo = new VarInfo();
/// <summary>
///TemperatureBaseForGrowth VarInfo definition
/// </summary>
public static VarInfo TemperatureBaseForGrowthVarInfo
{
get { return _TemperatureBaseForGrowthVarInfo; }
}
private static VarInfo _StartDateVarInfo = new VarInfo();
/// <summary>
///StartDate VarInfo definition
/// </summary>
public static VarInfo StartDateVarInfo
{
get { return _StartDateVarInfo; }
}
private static VarInfo _EndDateVarInfo = new VarInfo();
/// <summary>
///EndDate VarInfo definition
/// </summary>
public static VarInfo EndDateVarInfo
{
get { return _EndDateVarInfo; }
}
//Parameters static VarInfo list of the composite class
#endregion
#region pre/post conditions management
/// <summary>
/// Test to verify the postconditions
/// </summary>
public string TestPostConditions(UNIMI.ClimIndices.Interfaces.DataWeather dataweather, UNIMI.ClimIndices.Interfaces.UnivariateDataWeather univariatedataweather, UNIMI.ClimIndices.Interfaces.DataClimIndices dataclimindices, string callID)
{
try
{
//Set current values of the outputs to the static VarInfo representing the output properties of the domain classes
//Create the collection of the conditions to test
ConditionsCollection prc = new ConditionsCollection();
Preconditions pre = new Preconditions();
//GENERATED CODE END - PLACE YOUR CUSTOM CODE BELOW - Section4
//Code written below will not be overwritten by a future code generation
//End of custom code. Do not place your custom code below. It will be overwritten by a future code generation.
//PLACE YOUR CUSTOM CODE ABOVE - GENERATED CODE START - Section4
//Get the evaluation of postconditions
string postConditionsResult = pre.VerifyPostconditions(prc, callID);
//if we have errors, send it to the configured output
if (!string.IsNullOrEmpty(postConditionsResult)) { pre.TestsOut(postConditionsResult, true, "PostConditions errors in component ClimIndices.Extension, strategy " + this.GetType().Name); }
return postConditionsResult;
}
catch (Exception exception)
{
//Uncomment the next line to use the trace
//TraceStrategies.TraceEvent(System.Diagnostics.TraceEventType.Error, 1001, "Strategy: " + this.GetType().Name + " - Unhandled exception running post-conditions");
string msg = "Component ClimIndices.Extension, " + this.GetType().Name + ": Unhandled exception running post-condition test. ";
throw new Exception(msg, exception);
}
}
/// <summary>
/// Test to verify the preconditions
/// </summary>
public string TestPreConditions(UNIMI.ClimIndices.Interfaces.DataWeather dataweather, UNIMI.ClimIndices.Interfaces.UnivariateDataWeather univariatedataweather, UNIMI.ClimIndices.Interfaces.DataClimIndices dataclimindices, string callID)
{
try
{
//Set current values of the inputs to the static VarInfo representing the input properties of the domain classes
UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMaximum.CurrentValue = dataweather.AirTemperatureMaximum;
UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMinimum.CurrentValue = dataweather.AirTemperatureMinimum;
//Create the collection of the conditions to test
ConditionsCollection prc = new ConditionsCollection();
Preconditions pre = new Preconditions();
RangeBasedCondition r1 = new RangeBasedCondition(UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMaximum);
if (r1.ApplicableVarInfoValueTypes.Contains(UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMaximum.ValueType)) { prc.AddCondition(r1); }
RangeBasedCondition r2 = new RangeBasedCondition(UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMinimum);
if (r2.ApplicableVarInfoValueTypes.Contains(UNIMI.ClimIndices.Interfaces.DataWeatherVarInfo.AirTemperatureMinimum.ValueType)) { prc.AddCondition(r2); }
prc.AddCondition(new RangeBasedCondition(_modellingOptionsManager.GetParameterByName("TemperatureBaseForGrowth")));
prc.AddCondition(new RangeBasedCondition(_modellingOptionsManager.GetParameterByName("StartDate")));
prc.AddCondition(new RangeBasedCondition(_modellingOptionsManager.GetParameterByName("EndDate")));
//GENERATED CODE END - PLACE YOUR CUSTOM CODE BELOW - Section3
//Code written below will not be overwritten by a future code generation
//End of custom code. Do not place your custom code below. It will be overwritten by a future code generation.
//PLACE YOUR CUSTOM CODE ABOVE - GENERATED CODE START - Section3
//Get the evaluation of preconditions;
string preConditionsResult = pre.VerifyPreconditions(prc, callID);
//if we have errors, send it to the configured output
if (!string.IsNullOrEmpty(preConditionsResult)) { pre.TestsOut(preConditionsResult, true, "PreConditions errors in component ClimIndices.Extension, strategy " + this.GetType().Name); }
return preConditionsResult;
}
catch (Exception exception)
{
//Uncomment the next line to use the trace
// TraceStrategies.TraceEvent(System.Diagnostics.TraceEventType.Error, 1002,"Strategy: " + this.GetType().Name + " - Unhandled exception running pre-conditions");
string msg = "Component ClimIndices.Extension, " + this.GetType().Name + ": Unhandled exception running pre-condition test. ";
throw new Exception(msg, exception);
}
}
#endregion
#region Model
/// <summary>
/// Run the strategy to calculate the outputs. In case of error during the execution, the preconditions tests are executed.
/// </summary>
public void Estimate(UNIMI.ClimIndices.Interfaces.DataWeather dataweather, UNIMI.ClimIndices.Interfaces.UnivariateDataWeather univariatedataweather, UNIMI.ClimIndices.Interfaces.DataClimIndices dataclimindices)
{
try
{
CalculateModel(dataweather, univariatedataweather, dataclimindices);
//Uncomment the next line to use the trace
//TraceStrategies.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 1005,"Strategy: " + this.GetType().Name + " - Model executed");
}
catch (Exception exception)
{
//Uncomment the next line to use the trace
//TraceStrategies.TraceEvent(System.Diagnostics.TraceEventType.Error, 1003, "Strategy: " + this.GetType().Name + " - Unhandled exception running model");
string msg = "Error in component ClimIndices.Extension, strategy: " + this.GetType().Name + ": Unhandled exception running model. " + exception.GetType().FullName + " - " + exception.Message;
throw new Exception(msg, exception);
}
}
private void CalculateModel(UNIMI.ClimIndices.Interfaces.DataWeather dataweather, UNIMI.ClimIndices.Interfaces.UnivariateDataWeather univariatedataweather, UNIMI.ClimIndices.Interfaces.DataClimIndices dataclimindices)
{
//GENERATED CODE END - PLACE YOUR CUSTOM CODE BELOW - Section1
//Code written below will not be overwritten by a future code generation
DataClimIndicesExtended dce = dataclimindices as DataClimIndicesExtended;
if (dce != null)
{
int i;
int start = StartDate;
int end = EndDate;
double[] Tavg = new double[365];
double[] GDD = new double[365];
double GDDCustomPeriod = 0;
for (i = 0; i < 365; i++)
{
Tavg[i] = (dataweather.AirTemperatureMaximum[i] + dataweather.AirTemperatureMinimum[i]) / 2;
}
for (i = (start - 1); i < (end); i++)
{
GDD[i] = Tavg[i] - TemperatureBaseForGrowth;
GDDCustomPeriod = GDDCustomPeriod + GDD[i];
}
//DoubleVector GDDdv = new DoubleVector(GDD);
dce.GDDCustomPeriod = GDDCustomPeriod;// NMathFunctions.DoubleSumFunction(GDDdv);
}
else
{
System.Windows.Forms.MessageBox.Show(
"This strategy requires a DataClimIndicesExtended domain class passed as DataCLimiIndices.");
}
//End of custom code. Do not place your custom code below. It will be overwritten by a future code generation.
//PLACE YOUR CUSTOM CODE ABOVE - GENERATED CODE START - Section1
}
#endregion
//GENERATED CODE END - PLACE YOUR CUSTOM CODE BELOW - Section2
//Code written below will not be overwritten by a future code generation
//End of custom code. Do not place your custom code below. It will be overwritten by a future code generation.
//PLACE YOUR CUSTOM CODE ABOVE - GENERATED CODE START - Section2
}
}
Created with the Personal Edition of HelpNDoc: Easily create EPub books