Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JsonTemplateInstantiator.cs @ 17442

Last change on this file since 17442 was 17442, checked in by dpiringe, 4 years ago

#3026:

  • added new CLI argument StringArgument
  • removed unnecessary check in StartArgument
  • changed output format from simple .txt to .json in HeuristicLab.JsonInterface.App.Runner
  • user has to enter output path now when executing JsonInterface on console
File size: 5.0 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.Reflection;
7using System.Text;
8using System.Threading.Tasks;
9using HEAL.Attic;
10using HeuristicLab.Core;
11using HeuristicLab.Data;
12using HeuristicLab.Optimization;
13using Newtonsoft.Json.Linq;
14
15namespace HeuristicLab.JsonInterface {
16  /// <summary>
17  /// Static class to instantiate an IAlgorithm object with a json interface template and config.
18  /// </summary>
19  public static class JsonTemplateInstantiator {
20    private struct InstData {
21      public JToken Template { get; set; }
22      public JArray Config { get; set; }
23      public IDictionary<string, IJsonItem> Objects { get; set; }
24      public IOptimizer Optimizer { get; set; }
25    }
26
27    public static IOptimizer Instantiate(string templateFile) =>
28      Instantiate(templateFile, null, out IEnumerable<string> allowedResultNames);
29
30
31    public static IOptimizer Instantiate(string templateFile, out IEnumerable<string> allowedResultNames) =>
32      Instantiate(templateFile, null, out allowedResultNames);
33
34   
35
36    /// <summary>
37    /// Instantiate an IAlgorithm object with a template and config.
38    /// </summary>
39    /// <param name="templateFile">Template file (json), generated with JCGenerator.</param>
40    /// <param name="configFile">Config file (json) for the template.</param>
41    /// <returns>confugrated IOptimizer object</returns>
42    public static IOptimizer Instantiate(string templateFile, string configFile, out IEnumerable<string> allowedResultNames) {
43      InstData instData = new InstData() {
44        Objects = new Dictionary<string, IJsonItem>()
45      };
46
47      // parse template and config files
48      instData.Template = JToken.Parse(File.ReadAllText(templateFile));
49      if(!string.IsNullOrEmpty(configFile))
50        instData.Config = JArray.Parse(File.ReadAllText(configFile));
51
52      // extract metadata information
53      string optimizerName = instData.Template[Constants.Metadata][Constants.TemplateName].ToString();
54      string hLFileLocation = Path.GetFullPath(instData.Template[Constants.Metadata][Constants.HLFileLocation].ToString());
55
56      // deserialize hl file
57      ProtoBufSerializer serializer = new ProtoBufSerializer();
58      IOptimizer optimizer = (IOptimizer)serializer.Deserialize(hLFileLocation);
59      instData.Optimizer = optimizer;
60
61      // collect all parameterizedItems from template
62      CollectParameterizedItems(instData);
63     
64      // if config != null -> merge Template and Config
65      if (instData.Config != null)
66        MergeTemplateWithConfig(instData);
67
68      // get algorthm data and object
69      IJsonItem optimizerData = instData.Objects.First().Value;
70     
71      // inject configuration
72      JsonItemConverter.Inject(optimizer, optimizerData);
73
74      allowedResultNames = CollectResults(instData);
75
76      return optimizer;
77    }
78
79    #region Helper
80
81    private static object GetValueFromJObject(JObject obj) =>
82      obj[nameof(IJsonItem.Value)]?.ToObject<object>();
83
84    private static IEnumerable<string> CollectResults(InstData instData) {
85      IList<string> res = new List<string>();
86      foreach(JObject obj in instData.Template[Constants.Results]) {
87        res.Add(obj.Property("Name").Value.ToString());
88      }
89      return res;
90    }
91
92    private static void CollectParameterizedItems(InstData instData) {
93      IJsonItem root = JsonItemConverter.Extract(instData.Optimizer);
94      instData.Objects.Add(root.Path, root);
95
96      foreach (JObject obj in instData.Template[Constants.Parameters]) {
97        string[] pathParts = obj.Property("Path").Value.ToString().Split('.');
98        IJsonItem tmp = root;
99        IJsonItem old = null;
100        for(int i = 1; i < pathParts.Length; ++i) {
101          foreach(var c in tmp.Children) {
102            if (c.Name == pathParts[i])
103              tmp = c;
104          }
105          if (old == tmp)
106            throw new Exception($"Invalid path '{string.Join(".", pathParts)}'");
107          else old = tmp;
108        }
109        tmp.Value = GetValueFromJObject(obj);
110        tmp.Range = obj[nameof(IJsonItem.Range)]?.ToObject<object[]>();
111        tmp.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
112        instData.Objects.Add(tmp.Path, tmp);
113      }
114    }
115   
116    private static void MergeTemplateWithConfig(InstData instData) {
117      foreach (JObject obj in instData.Config) {
118        // build item from config object
119        string path = obj.Property("Path").Value.ToString();
120        // override default value
121        if (instData.Objects.TryGetValue(path, out IJsonItem param)) {
122          param.Value = GetValueFromJObject(obj);
123          // override ActualName (for LookupParameters)
124          if (param.ActualName != null)
125            param.ActualName = obj[nameof(IJsonItem.ActualName)]?.ToString();
126        } else throw new InvalidDataException($"No parameter with path='{path}' defined!");
127      }
128    }
129    #endregion
130  }
131}
Note: See TracBrowser for help on using the repository browser.