From 4708affe082575518e29bcfb1e13c0cfad7425db Mon Sep 17 00:00:00 2001
From: Stefano Borini <sborini@enthought.com>
Date: Fri, 21 Jul 2017 15:05:13 +0100
Subject: [PATCH] Various changes to include parameter names

---
 .../dummy_mco/dakota/dakota_communicator.py   | 17 +++++++---
 .../dummy_mco/dakota/dakota_model.py          |  4 +--
 .../dummy_mco/dakota/dakota_optimizer.py      | 32 ++++++++++++++++---
 .../data_sources/data_source_parameters.py    |  1 +
 force_bdss/mco/base_mco_model.py              |  5 ++-
 force_bdss/tests/fixtures/test_csv.json       |  1 -
 force_bdss/workspecs/mco_parameters.py        | 13 ++++++++
 7 files changed, 58 insertions(+), 15 deletions(-)
 create mode 100644 force_bdss/workspecs/mco_parameters.py

diff --git a/force_bdss/core_plugins/dummy_mco/dakota/dakota_communicator.py b/force_bdss/core_plugins/dummy_mco/dakota/dakota_communicator.py
index ee349e8..1b81684 100644
--- a/force_bdss/core_plugins/dummy_mco/dakota/dakota_communicator.py
+++ b/force_bdss/core_plugins/dummy_mco/dakota/dakota_communicator.py
@@ -8,13 +8,20 @@ class DakotaCommunicator(BaseMCOCommunicator):
     def receive_from_mco(self):
         data = sys.stdin.read()
         values = list(map(float, data.split()))
-        value_types = self.model.value_types
-        if len(values) != len(value_types):
-            raise ValueError("Length of provided data differs from the number "
-                             "of expected types. {} {}".format(values,
-                                                               value_types))
+        parameters = self.model.parameters
+
+        if len(values) != len(parameters):
+            raise ValueError(
+                "The passed information length is {}, but the model "
+                "specifies {} values.".format(
+                    len(values), len(parameters)
+                    ))
+
+        value_types = [p.type for p in parameters]
+        value_names = [p.name for p in parameters]
 
         return DataSourceParameters(
+            value_names=value_names,
             value_types=value_types,
             values=numpy.array(values)
         )
diff --git a/force_bdss/core_plugins/dummy_mco/dakota/dakota_model.py b/force_bdss/core_plugins/dummy_mco/dakota/dakota_model.py
index b4c081a..3c0d14a 100644
--- a/force_bdss/core_plugins/dummy_mco/dakota/dakota_model.py
+++ b/force_bdss/core_plugins/dummy_mco/dakota/dakota_model.py
@@ -1,7 +1,5 @@
-from traits.api import List, String
-
 from force_bdss.api import BaseMCOModel
 
 
 class DakotaModel(BaseMCOModel):
-    value_types = List(String)
+    pass
diff --git a/force_bdss/core_plugins/dummy_mco/dakota/dakota_optimizer.py b/force_bdss/core_plugins/dummy_mco/dakota/dakota_optimizer.py
index 6b607cf..485a3d6 100644
--- a/force_bdss/core_plugins/dummy_mco/dakota/dakota_optimizer.py
+++ b/force_bdss/core_plugins/dummy_mco/dakota/dakota_optimizer.py
@@ -1,14 +1,34 @@
 import subprocess
-
 import sys
+import itertools
+import collections
 
 from force_bdss.api import BaseMultiCriteriaOptimizer
 
 
+def rotated_range(start, stop, starting_value):
+    r = list(range(start, stop))
+    start_idx = r.index(starting_value)
+    d = collections.deque(r)
+    d.rotate(-start_idx)
+    return list(d)
+
+
 class DakotaOptimizer(BaseMultiCriteriaOptimizer):
     def run(self):
-        print("Running dakota optimizer")
-        for initial_value in range(10):
+        parameters = self.model.parameters
+
+        values = []
+        for p in parameters:
+            values.append(
+                rotated_range(p.lower_bound,
+                              p.upper_bound,
+                              p.initial_value)
+            )
+
+        value_iterator = itertools.product(*values)
+
+        for value in value_iterator:
             ps = subprocess.Popen(
                 [sys.argv[0],
                  "--evaluate",
@@ -16,5 +36,7 @@ class DakotaOptimizer(BaseMultiCriteriaOptimizer):
                 stdout=subprocess.PIPE,
                 stdin=subprocess.PIPE)
 
-            out = ps.communicate("{}".format(initial_value).encode("utf-8"))
-            print("{}: {}".format(initial_value, out[0].decode("utf-8")))
+            out = ps.communicate(
+                " ".join([str(v) for v in value]).encode("utf-8"))
+            print("{}: {}".format(" ".join([str(v) for v in value]),
+                                  out[0].decode("utf-8")))
diff --git a/force_bdss/data_sources/data_source_parameters.py b/force_bdss/data_sources/data_source_parameters.py
index c45915d..6e33d16 100644
--- a/force_bdss/data_sources/data_source_parameters.py
+++ b/force_bdss/data_sources/data_source_parameters.py
@@ -2,5 +2,6 @@ from traits.api import HasStrictTraits, Array, List, String
 
 
 class DataSourceParameters(HasStrictTraits):
+    value_names = List(String)
     value_types = List(String)
     values = Array(shape=(None,))
diff --git a/force_bdss/mco/base_mco_model.py b/force_bdss/mco/base_mco_model.py
index e746635..acdebfb 100644
--- a/force_bdss/mco/base_mco_model.py
+++ b/force_bdss/mco/base_mco_model.py
@@ -1,5 +1,6 @@
-from traits.api import ABCHasStrictTraits, Instance
+from traits.api import ABCHasStrictTraits, Instance, List
 
+from ..workspecs.mco_parameters import MCOParameter
 from .i_multi_criteria_optimizer_bundle import IMultiCriteriaOptimizerBundle
 
 
@@ -17,6 +18,8 @@ class BaseMCOModel(ABCHasStrictTraits):
                       visible=False,
                       transient=True)
 
+    parameters = List(MCOParameter)
+
     def __init__(self, bundle, *args, **kwargs):
         self.bundle = bundle
         super(BaseMCOModel, self).__init__(*args, **kwargs)
diff --git a/force_bdss/tests/fixtures/test_csv.json b/force_bdss/tests/fixtures/test_csv.json
index 1c15b0f..f061c10 100644
--- a/force_bdss/tests/fixtures/test_csv.json
+++ b/force_bdss/tests/fixtures/test_csv.json
@@ -4,7 +4,6 @@
     "multi_criteria_optimizer": {
       "id": "force.bdss.bundles.enthought.dakota",
       "model_data": {
-        "value_types": ["DUMMY"]
       }
     },
     "data_sources": [
diff --git a/force_bdss/workspecs/mco_parameters.py b/force_bdss/workspecs/mco_parameters.py
new file mode 100644
index 0000000..5020117
--- /dev/null
+++ b/force_bdss/workspecs/mco_parameters.py
@@ -0,0 +1,13 @@
+from traits.api import HasStrictTraits, String, Float
+
+
+class MCOParameter(HasStrictTraits):
+    pass
+
+
+class RangedMCOParameter(MCOParameter):
+    name = String()
+    value_type = String()
+    initial_value = Float()
+    upper_bound = Float()
+    lower_bound = Float()
-- 
GitLab