Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 12747 was 9215, checked in by fschoepp, 12 years ago

#1888:

  • Janitor is now working as expected in Windows Azure
  • Added basic support for experiments (draggable experiments)
  • Added methods to save/read experiments from TableStorage
  • The job status can now be retrieved by using the GetTasks/GetTaskData methods
  • Added a class to convert JSON-objects to Algorithm instances
  • Web page: Added experiment button to navigation
File size: 11.7 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;
9using HeuristicLab.Services.Optimization.ControllerService.Azure;
10using HeuristicLab.Services.Optimization.ControllerService.Interfaces;
11using System.Diagnostics;
12
13namespace HeuristicLab.Services.Optimization.ControllerService {
14  public class ScenarioParser {
15    private static IList<Model.OptimizationScenario> scenarios;
16    private static object lockable = new object();
17
18    private IDataAccessLayer dal = DataAccessLayerProvider.GetLayer();
19
20    public IList<Model.OptimizationScenario> Scenarios {
21      get {
22        if (scenarios == null) {
23          lock (lockable) {
24            if (scenarios == null) {
25              ParseScenarios();
26            }
27          }
28        }
29        return scenarios;
30      }
31    }
32   
33    public Model.OptimizationScenario GetByName(string name) {
34      foreach (var scen in Scenarios) {
35        if (scen.Id == name) {
36          return scen;
37        }
38      }
39      return null;
40    }
41
42    /*// http://www.sascha-dittmann.de/post/Webseitenpfade-einer-Windows-Azure-Web-Rolle-bestimmen.aspx
43    private static IEnumerable<string> WebSiteDirectories {
44      get {
45        var roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
46        if (roleRootDir == null)
47          return Enumerable.Empty<string>();
48        XNamespace roleModelNs =
49          "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
50        var roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
51        if (roleModelDoc.Root == null)
52          return Enumerable.Empty<string>();
53
54        var sites = roleModelDoc.Root.Element(roleModelNs + "Sites");
55        if (sites == null)
56          return Enumerable.Empty<string>();
57
58        var siteElements = sites.Elements(roleModelNs + "Site");
59
60        return
61          from siteElement in siteElements
62          where siteElement.Attribute("name") != null
63                && siteElement.Attribute("name").Value == "Web"
64                && siteElement.Attribute("physicalDirectory") != null
65          select Path.Combine(roleRootDir,
66                 siteElement.Attribute("physicalDirectory").Value);
67      }
68    }
69     */
70
71    private void ParseScenarios() {
72      var scens = new List<Model.OptimizationScenario>();
73      /*string path;
74      if (WebSiteDirectories.Count() != 0) {
75        path = WebSiteDirectories.FirstOrDefault() + @"\Mappings";
76      } else {
77        path = AppDomain.CurrentDomain.BaseDirectory + @"\Mappings";
78      }
79       
80      foreach (var file in Directory.EnumerateFiles(path, "*.xml")) {
81        var scenario = ParseScenarioFromFile(file);
82        if (scenario != null)
83          scens.Add(scenario);
84      }*/
85
86      var scenarioDao = dal.ScenarioDao;
87      var blobDao = dal.BlobDao;
88      foreach (var entity in scenarioDao.GetAllEntities()) {
89        var scenarioXml = blobDao.FindByKey(entity.Scenario).Text;
90        var scenario = ParseScenarioFromXml(scenarioXml);
91        if (scenario != null)
92          scens.Add(scenario);
93      }
94
95      scenarios = scens;
96    }
97
98    private XmlReaderSettings GetSettings() {
99      // Set the validation settings.
100      XmlReaderSettings settings = new XmlReaderSettings();
101      settings.ValidationType = ValidationType.Schema;
102      settings.Schemas.Add("urn:scenario-schema", AppDomain.CurrentDomain.BaseDirectory + @"\Mappings\scenario.xsd");     
103      return settings;
104    }
105
106    public Model.OptimizationScenario ParseScenarioFromXml(string xml) {
107      //using (var reader = XmlReader.Create(new StringReader(xml), GetSettings())) {
108        return ParseScenario(new StringReader(xml));
109      //}           
110    }
111
112   /* private Model.OptimizationScenario ParseScenarioFromFile(string filename) {
113      using (var reader = XmlReader.Create(new FileStream(filename, FileMode.Open), GetSettings())) {
114        return ParseScenario(reader);
115      }     
116    } */
117
118    private Model.Problem ParseProblem(XmlReader reader) {
119      var problem = new Model.Problem();
120      while (reader.Read()) {
121        if (reader.NodeType == XmlNodeType.EndElement)
122          break;
123        if (reader.Name == "parameters")
124          problem.Parameters.Items = ParseParameters(reader);
125      }
126      return problem;
127    }
128
129    private void ParseAlgorithms(out IList<Model.Algorithm> algos, XmlReader reader) {
130      algos = new List<Model.Algorithm>();
131      var depth = reader.Depth;
132      do {
133        if (reader.Name == "algorithm" && reader.Depth == depth) {
134          var innerAlg = new Model.Algorithm();
135          algos.Add(innerAlg);
136         
137          innerAlg.Mapper = reader.GetAttribute("mapper");
138          reader.Read();
139          for (;;) {
140            if (reader.Name == "algorithm" && reader.NodeType == XmlNodeType.EndElement)
141              break;
142
143            if (reader.Name == "parameters" && reader.NodeType == XmlNodeType.Element) {
144              innerAlg.Parameters.Items = ParseParameters(reader);
145              continue;
146            }
147            else if (reader.Name == "problem" && reader.NodeType == XmlNodeType.Element) {
148              innerAlg.Problem = ParseProblem(reader);
149              continue;
150            }
151            else if (reader.Name == "algorithm" && reader.NodeType == XmlNodeType.Element) {
152              IList<Model.Algorithm> childAlgos;
153              ParseAlgorithms(out childAlgos, reader);
154              innerAlg.ChildAlgorithms = childAlgos;
155              //TODO: Test with child algorithms
156              continue;
157            }
158            reader.Read();
159          }
160        }
161      } while (reader.Read() && reader.Depth >= depth);
162    }
163
164    private Model.OptimizationScenario ParseScenarioElement(XmlReader reader) {
165      var scenario = new Model.OptimizationScenario();
166      var depth = reader.Depth;
167      while (reader.Depth >= depth) {
168        if (reader.Name == "scenario" && reader.NodeType == XmlNodeType.EndElement)
169          break;
170
171        if (reader.Name == "name") {
172          scenario.Id = reader.ReadElementContentAsString();
173          continue;
174        }
175        else if (reader.Name == "algorithm") {
176          IList<Model.Algorithm> algos;
177          ParseAlgorithms(out algos, reader);
178          scenario.Algorithm = algos;
179          continue;
180        }
181        reader.Read();
182      }
183      return scenario;
184    }
185
186    private Model.OptimizationScenario ParseScenario(StringReader str) {
187      // Set the validation settings.     
188      bool isErrorPresent = false;
189      var settings = GetSettings();
190      settings.ValidationEventHandler += (sender, args) => {
191        Trace.WriteLine(args.Message);
192        isErrorPresent = true;
193      };
194      Model.OptimizationScenario scenario = null;     
195      using (var reader = XmlReader.Create(str, settings)) {       
196        while (!reader.EOF) {
197          if (reader.Name == "scenario" && reader.NodeType == XmlNodeType.Element) {
198            scenario = ParseScenarioElement(reader);           
199          }
200          reader.Read();
201        }
202      }
203     
204      if (isErrorPresent)
205        return null;
206      return scenario;
207    }
208
209    struct ValueEntry {
210      public double v1;
211      public double v2;
212    };
213
214    private void ParseDecimalMatrix(Model.DecimalMatrix matrix, XmlReader reader) {     
215      IList<ValueEntry> ventries = new List<ValueEntry>();
216      while (reader.Read()) {       
217        if (reader.Name == "param")
218          break;
219        if (reader.Name == "value") {
220          var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
221          var val2 = Convert.ToDouble(reader.GetAttribute("v2"), CultureInfo.InvariantCulture.NumberFormat);
222          ventries.Add(new ValueEntry() { v1 = val1, v2 = val2 });         
223        }
224      }
225      double[][] mat = new double[ventries.Count][];
226      int i=0;
227      foreach (var entry in ventries) {
228        mat[i] = new double[2];
229        mat[i][0] = entry.v1;
230        mat[i][1] = entry.v2;
231        i++;
232      }
233      matrix.Value = mat;
234    }
235
236    private IList<Model.Parameter> ParseParameters(XmlReader reader) {
237      IList<Model.Parameter> parameters = new List<Model.Parameter>();
238      while (reader.Read()) {
239        if (reader.Name == "parameters" && reader.NodeType == XmlNodeType.EndElement)
240          break;
241        // parse parameter
242        if (reader.Name == "param" && reader.NodeType == XmlNodeType.Element) {
243          var param = new Model.Parameter();
244          var typeAtt = reader.GetAttribute("type");
245          param.Type = (Model.ParameterType)Enum.Parse(typeof(Model.ParameterType), typeAtt);
246          switch (param.Type) {
247            case Model.ParameterType.Boolean:
248              param.Value = new Model.BoolValue() { Name = reader.GetAttribute("name"), Value = Convert.ToBoolean(reader.GetAttribute("value")) };
249              break;
250            case Model.ParameterType.Integer:
251            case Model.ParameterType.Percent:
252            case Model.ParameterType.Decimal:
253              //TODO: Check which comma char is being used; enhance to use any
254              param.Value = new Model.DecimalValue() { Name = reader.GetAttribute("name"), Value = Convert.ToDouble(reader.GetAttribute("value"), CultureInfo.InvariantCulture.NumberFormat) };
255              break;           
256            case Model.ParameterType.DecimalMatrix:
257              var decMatrix = new Model.DecimalMatrix() { Name = reader.GetAttribute("name") };
258              ParseDecimalMatrix(decMatrix, reader);
259              param.Value = decMatrix;
260              break;
261            case Model.ParameterType.DecimalVector:
262              var decVec = new Model.DecimalVector() { Name = reader.GetAttribute("name") };
263              ParseDecimalVector(decVec, reader);
264              param.Value = decVec;
265              break;
266            case Model.ParameterType.Type:
267              var type = new Model.TypeValue() { Name = reader.GetAttribute("name") };
268              ParseType(type, reader);
269              param.Value = type;
270              break;
271            case Model.ParameterType.String:
272              param.Value = new Model.StringValue() { Name = reader.GetAttribute("name"), Value = reader.GetAttribute("value") };
273              break;
274            default:
275              Console.WriteLine("Unhandled model type: " + param.Type);
276              break;
277          }
278          parameters.Add(param);
279        }
280      }
281      return parameters;
282    }
283
284    private void ParseType(Model.TypeValue type, XmlReader reader) {
285      var choices = new List<string>();
286      string selected = null;
287      while (reader.Read()) {
288        if (reader.Name == "param")
289          break;
290        if (reader.Name == "choice") {
291          var choice = reader.GetAttribute("name");
292          if (reader.HasAttributes && Convert.ToBoolean(reader.GetAttribute("selected"))) {           
293            selected = choice;
294          }
295          choices.Add(choice);
296        }
297      }
298      type.Options = choices.ToArray();
299      type.Value = selected;
300    }
301
302    private void ParseDecimalVector(Model.DecimalVector decVec, XmlReader reader) {
303      var entries = new List<double>();
304      //IList<ValueEntry> ventries = new List<ValueEntry>();
305      while (reader.Read()) {
306        if (reader.Name == "param")
307          break;
308        if (reader.Name == "value") {
309          var val1 = Convert.ToDouble(reader.GetAttribute("v1"), CultureInfo.InvariantCulture.NumberFormat);
310          entries.Add(val1);
311        }
312      }
313      decVec.Value = entries.ToArray();     
314    }
315  }
316}
Note: See TracBrowser for help on using the repository browser.