Optimization Plugin Complete

The following code corresponds to the full optimization plugin example written based on the scaffolding from the Optimization Plugin Template page.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace OptimPluginSample
{
    public class PluginSample
    {
        private double _incrementValue = 0;
        private int _iterationNumber = 0;

        private IDictionary<string, string> _variableNames = new Dictionary<string, string>();
        private IDictionary<string, double> _variableValues = new Dictionary<string, double>();

        private IDictionary<string, string> _targetNames = new Dictionary<string, string>();
        private IDictionary<string, double> _targetValues = new Dictionary<string, double>();

        private IList<IDictionary<string,double>> _iterationResults = new List<IDictionary<string,double>>();

        private string _simulationName = string.Empty;
        private string _reportPath = string.Empty;

        public PluginSample(string arguments)
        {
            // splint the list of parameters
            var argumentsList=  arguments.Split(',');

            // check that the argument list represents the number of arguments that we need
            if(argumentsList.Length != 2)
            {
                throw new ArgumentException("We should only have two arguments");
            }

            // try to read the first argument as the increment value
            if (double.TryParse(argumentsList[0], out var incrementValue))
            {
                _incrementValue = incrementValue;
            }
            else
            {
                throw new ArgumentException("first argument cannot be read as a double for increment value");
            }

            // try the read the second argument as the iteration number
            if (int.TryParse(argumentsList[1], out var iterationNumber))
            {
                _iterationNumber = iterationNumber;
            }
            else
            {
                throw new ArgumentException("second argument cannot be read as a int for iteration number");
            }
        }

        /// <summary>
        ///     Callback called upon starting the optimization loop (optional)
        /// </summary>
        public void StartRun()
        {

        }

        /// <summary>
        ///     Callback called upon starting a new iteration in the optimization loop
        /// </summary>
        /// <param name="iteration">the iteration that is starting</param>
        /// <returns> whether we should continue on this iteration or not</returns>
        public bool StartIteration(int iteration)
        {
            if(iteration >= _iterationNumber)
            {
                WriteReport();
                return false;
            }
            var keys = _variableValues.Keys.ToArray();
            foreach (var key in keys)
            {
                _variableValues[key] = _variableValues[key] + _incrementValue;
            }

            return true; // we want to continue looping on this iteration
        }
        /// <summary>
        ///     Callback called upon ending an iteration   (optional)
        /// </summary>
        /// <param name="iteration">the iteration that is ending</param>
        public void EndIteration(int iteration)
        {
            _iterationResults.Add(_targetValues.ToDictionary(entry => entry.Key, entry => entry.Value));
        }

        /// <summary>
        ///     Called to return the new value to set for this parameter
        /// </summary>
        public double GetNewValue(string parameterId)
        {
            return _variableValues[parameterId];
        }

        /// <summary>
        ///     Called to register a new variable as input
        /// </summary>
        public void AddVariable(string parameterId, string parameterUserName, double startingValue, double min, double max)
        {
            _variableNames.Add(parameterId, parameterUserName);
            _variableValues.Add(parameterId, startingValue);
        }

        /// <summary>
        ///    Called to register a new target as output (optional)
        /// </summary>
        public void AddTarget(string parameterId, string parameterUserName, double startingValue, double targetValue, double weight)
        {
            _targetNames.Add(parameterId, parameterUserName);
            _targetValues.Add(parameterId, startingValue);
        }

        /// <summary>
        ///     Callback called after the simulation's update to update the values of the targets
        /// </summary>
        /// <param name="parameterId"></param>
        /// <param name="value"></param>
        public void SetMeasures(string parameterId, double value)
        {
            _targetValues[parameterId] = value;
        }

        /// <summary>
        ///     Callback called to inform the simulation details
        /// </summary>
        /// <param name="simulationName"></param>
        /// <param name="reportPath"></param>
        public void SetSimulationInfos(string simulationName, string reportPath)
        {
            _reportPath = reportPath ?? string.Empty;
            _simulationName= simulationName ?? string.Empty;
        }

        private void WriteReport()
        {
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine("<html><body><table>");

            stringBuilder.AppendLine("<tr><th>Iteration Number</th>");

            var parameterIdOrder = new string[_targetNames.Count];

            var idx = 0;
            foreach(var names in _targetNames)
            {
                stringBuilder.AppendLine($"<th>{names.Value}</th>");
                parameterIdOrder[idx] = names.Key;
                idx++;   
            }
            stringBuilder.AppendLine("<tr/>");

            idx = 0;
            foreach (var iterationResult in _iterationResults)
            {
                stringBuilder.AppendLine("<tr>");
                stringBuilder.AppendLine($"<td>{idx}</td>");
                foreach(var id in parameterIdOrder)
                {
                    stringBuilder.AppendLine($"<td>{iterationResult[id]}</td>");
                }
                stringBuilder.AppendLine("<tr/>");
                idx++;
            }

            stringBuilder.AppendLine("</table></body></html>");

            File.WriteAllText(_reportPath, stringBuilder.ToString());
        }

    }
}