Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Services.Optimization.Controller/ScenarioParser.cs @ 8916

Last change on this file since 8916 was 8817, checked in by fschoepp, 12 years ago

#1888:

  • Added a parser for independent scenarios (using the model of the optimization backend)
  • Optimization scenario sample can be found in mappings folder of the web project.
  • Added IScenarioMapper interface which provides functionality to map from the optimization data model to a backend model (e.g. Heuristic Lab data model)
  • Implementations of IScenarioMapper have to be provided as C# code (strings) which will be compiled by using a CSharpCodeProvider. Once compiled, the implementations of the IScenarioMapper are being cached within the platform for further usage.
  • Fixed a bug in web template DecimalMatrix (using i instead of j)
  • Added missing thumprint of localhost certificate to the optimization web project (ServiceConfiguration.Local.cscfg / ServiceConfiguration.Cloud.cscfg)
  • Test project now provides following test cases: Mapping types using IronPython and mapping types using Otis
File size: 8.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6using System.Xml;
7using System.Globalization;
8using System.Xml.Linq;
9
10namespace HeuristicLab.Services.Optimization.ControllerService {
11  public class ScenarioParser {
12    private static IList<Model.OptimizationScenario> scenarios;
13    private static object lockable = new object();
14
15    public IList<Model.OptimizationScenario> Scenarios {
16      get {
17        if (scenarios == null) {
18          lock (lockable) {
19            if (scenarios == null) {
20              ParseScenarios();
21            }
22          }
23        }
24        return scenarios;
25      }
26    }
27   
28    public Model.OptimizationScenario GetByName(string name) {
29      foreach (var scen in Scenarios) {
30        if (scen.Name == name) {
31          return scen;
32        }
33      }
34      return null;
35    }
36
37    // http://www.sascha-dittmann.de/post/Webseitenpfade-einer-Windows-Azure-Web-Rolle-bestimmen.aspx
38    private static IEnumerable<string> WebSiteDirectories {
39      get {
40        var roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
41        if (roleRootDir == null)
42          return Enumerable.Empty<string>();
43        XNamespace roleModelNs =
44          "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
45        var roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
46        if (roleModelDoc.Root == null)
47          return Enumerable.Empty<string>();
48
49        var sites = roleModelDoc.Root.Element(roleModelNs + "Sites");
50        if (sites == null)
51          return Enumerable.Empty<string>();
52
53        var siteElements = sites.Elements(roleModelNs + "Site");
54
55        return
56          from siteElement in siteElements
57          where siteElement.Attribute("name") != null
58                && siteElement.Attribute("name").Value == "Web"
59                && siteElement.Attribute("physicalDirectory") != null
60          select Path.Combine(roleRootDir,
61                 siteElement.Attribute("physicalDirectory").Value);
62      }
63    }
64
65    private void ParseScenarios() {
66      var scens = new List<Model.OptimizationScenario>();
67      string path;
68      if (WebSiteDirectories.Count() != 0) {
69        path = WebSiteDirectories.FirstOrDefault() + @"\Mappings";
70      } else {
71        path = AppDomain.CurrentDomain.BaseDirectory + @"\Mappings";
72      }
73       
74      foreach (var file in Directory.EnumerateFiles(path, "*.xml")) {
75        var scenario = ParseScenario(file);
76        if (scenario != null)
77          scens.Add(scenario);
78      }
79
80      scenarios = scens;
81    }
82
83    private Model.OptimizationScenario ParseScenario(string filename) {
84      // Set the validation settings.
85      XmlReaderSettings settings = new XmlReaderSettings();
86      settings.ValidationType = ValidationType.Schema;
87      settings.Schemas.Add("urn:scenario-schema", AppDomain.CurrentDomain.BaseDirectory + @"\Mappings\scenario.xsd");
88      bool isErrorPresent = false;
89      settings.ValidationEventHandler += (sender, args) => {
90        Console.WriteLine(args.Message);
91        isErrorPresent = true;
92      };
93      Model.OptimizationScenario scenario = null;
94      using (var reader = XmlReader.Create(filename, settings)) {
95        while (!isErrorPresent && reader.Read()) {
96          if (reader.Name == "scenario" && reader.NodeType == XmlNodeType.Element) {
97            scenario = new Model.OptimizationScenario();
98            scenario.ProblemType = reader.GetAttribute("mapper");
99            scenario.ProblemType = reader.GetAttribute("algorithmType");
100            scenario.ProblemType = reader.GetAttribute("problemType");
101          }
102          else if (reader.Name == "name") {
103            scenario.Name = reader.ReadElementContentAsString();           
104          }
105          else if (reader.Name == "problemParameters") {
106            IList<Model.Parameter> problemParameters = ParseParameters(reader);
107            foreach (var param in problemParameters)
108              scenario.InputParameters.Items.Add(param);
109          }
110          else if (reader.Name == "algorithmParameters") {
111            IList<Model.Parameter> algoParameters = ParseParameters(reader);
112            foreach (var param in algoParameters)
113              scenario.AlgorithmParameters.Items.Add(param);
114          }
115        }
116      }
117      if (isErrorPresent)
118        return null;
119      return scenario;
120    }
121
122    struct ValueEntry {
123      public double v1;
124      public double v2;
125    };
126
127    private void ParseDecimalMatrix(Model.DecimalMatrix matrix, XmlReader reader) {     
128      IList<ValueEntry> ventries = new List<ValueEntry>();
129      while (reader.Read()) {       
130        if (reader.Name == "param")
131          break;
132        if (reader.Name == "value") {
133          var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
134          var val2 = Convert.ToDouble(reader.GetAttribute("v2"), CultureInfo.InvariantCulture.NumberFormat);
135          ventries.Add(new ValueEntry() { v1 = val1, v2 = val2 });         
136        }
137      }
138      double[][] mat = new double[ventries.Count][];
139      int i=0;
140      foreach (var entry in ventries) {
141        mat[i] = new double[2];
142        mat[i][0] = entry.v1;
143        mat[i][1] = entry.v2;
144        i++;
145      }
146      matrix.Value = mat;
147    }
148
149    private IList<Model.Parameter> ParseParameters(XmlReader reader) {
150      IList<Model.Parameter> parameters = new List<Model.Parameter>();
151      while (reader.Read()) {
152        if (reader.Name.EndsWith("Parameters"))
153          break;
154        // parse parameter
155        if (reader.Depth == 2 && reader.Name == "param" && reader.NodeType == XmlNodeType.Element) {
156          var param = new Model.Parameter();
157          var typeAtt = reader.GetAttribute("type");
158          param.Type = (Model.ParameterType)Enum.Parse(typeof(Model.ParameterType), typeAtt);
159          switch (param.Type) {
160            case Model.ParameterType.Boolean:
161              param.Value = new Model.BoolValue() { Name = reader.GetAttribute("name"), Value = Convert.ToBoolean(reader.GetAttribute("value")) };
162              break;
163            case Model.ParameterType.Integer:
164            case Model.ParameterType.Percent:
165            case Model.ParameterType.Decimal:
166              //TODO: Check which comma char is being used; enhance to use any
167              param.Value = new Model.DecimalValue() { Name = reader.GetAttribute("name"), Value = Convert.ToDouble(reader.GetAttribute("value"), CultureInfo.InvariantCulture.NumberFormat) };
168              break;           
169            case Model.ParameterType.DecimalMatrix:
170              var decMatrix = new Model.DecimalMatrix() { Name = reader.GetAttribute("name") };
171              ParseDecimalMatrix(decMatrix, reader);
172              param.Value = decMatrix;
173              break;
174            case Model.ParameterType.DecimalVector:
175              var decVec = new Model.DecimalVector() { Name = reader.GetAttribute("name") };
176              ParseDecimalVector(decVec, reader);
177              param.Value = decVec;
178              break;
179            case Model.ParameterType.Type:
180              var type = new Model.TypeValue() { Name = reader.GetAttribute("name") };
181              ParseType(type, reader);
182              param.Value = type;
183              break;
184            case Model.ParameterType.String:
185              param.Value = new Model.StringValue() { Name = reader.GetAttribute("name"), Value = reader.GetAttribute("value") };
186              break;
187            default:
188              Console.WriteLine("Unhandled model type: " + param.Type);
189              break;
190          }
191          parameters.Add(param);
192        }
193      }
194      return parameters;
195    }
196
197    private void ParseType(Model.TypeValue type, XmlReader reader) {
198      var choices = new List<string>();
199      string selected = null;
200      while (reader.Read()) {
201        if (reader.Name == "param")
202          break;
203        if (reader.Name == "choice") {
204          var choice = reader.GetAttribute("name");
205          if (reader.HasAttributes && Convert.ToBoolean(reader.GetAttribute("selected"))) {           
206            selected = choice;
207          }
208          choices.Add(choice);
209        }
210      }
211      type.Options = choices.ToArray();
212      type.Value = selected;
213    }
214
215    private void ParseDecimalVector(Model.DecimalVector decVec, XmlReader reader) {
216      var entries = new List<double>();
217      //IList<ValueEntry> ventries = new List<ValueEntry>();
218      while (reader.Read()) {
219        if (reader.Name == "param")
220          break;
221        if (reader.Name == "value") {
222          var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
223          entries.Add(val1);
224        }
225      }
226      decVec.Value = entries.ToArray();     
227    }
228  }
229}
Note: See TracBrowser for help on using the repository browser.