From c03760eda2e1e9484164e49beda1500c7ba14c86 Mon Sep 17 00:00:00 2001
From: Stefano Borini <sborini@enthought.com>
Date: Thu, 13 Jul 2017 11:05:56 +0100
Subject: [PATCH] Added a few more KPIs and MCO

---
 examples/test_workflow.json                   |  5 ++-
 force_bdss/core_mco_driver.py                 | 31 +++++++++++++++++--
 ...key_performance_calculator.py => basic.py} |  6 ++--
 .../kpi/i_key_performance_calculator.py       |  4 ++-
 .../kpi/key_performance_calculators_plugin.py | 10 ++++--
 force_bdss/kpi/price.py                       | 11 +++++++
 force_bdss/kpi/viscosity.py                   | 11 +++++++
 ...c_multi_criteria_optimizer.py => basic.py} |  8 ++---
 force_bdss/mco/dakota.py                      | 17 ++++++++++
 .../mco/multi_criteria_optimizers_plugin.py   |  6 ++--
 .../workspecs/multi_criteria_optimization.py  |  2 +-
 force_bdss/workspecs/workflow.py              |  6 ++--
 12 files changed, 97 insertions(+), 20 deletions(-)
 rename force_bdss/kpi/{basic_key_performance_calculator.py => basic.py} (66%)
 create mode 100644 force_bdss/kpi/price.py
 create mode 100644 force_bdss/kpi/viscosity.py
 rename force_bdss/mco/{basic_multi_criteria_optimizer.py => basic.py} (62%)
 create mode 100644 force_bdss/mco/dakota.py

diff --git a/examples/test_workflow.json b/examples/test_workflow.json
index 4def5bb..1bbd366 100644
--- a/examples/test_workflow.json
+++ b/examples/test_workflow.json
@@ -1,6 +1,9 @@
 {
     "multi_criteria_optimization": {
         "name": "basic"
-    }
+    },
+    "key_performance_indicators": [
+        "viscosity", "price"
+    ]
 }
 
diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index c3625fc..652aa58 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -31,9 +31,34 @@ class CoreMCODriver(Plugin):
 
     @on_trait_change("application:started")
     def application_started(self):
+        workflow = self.application.workflow
         if self.application.evaluate:
-            for kpi in self.key_performance_calculators:
-                kpi.run(self.application)
+            for kpi in workflow.key_performance_indicators:
+                kpc = self._find_kpc_by_computes(kpi)
+                if kpc:
+                    kpc.run(self.application)
+                else:
+                    raise Exception("Requested KPI {} but don't know how"
+                                    "to compute it.".format(kpi))
         else:
-            for mco in self.multi_criteria_optimizers:
+            mco_name = workflow.multi_criteria_optimization.name
+            mco = self._find_mco_by_name(mco_name)
+            if mco:
                 mco.run(self.application)
+            else:
+                raise Exception("Requested MCO {} but it's not available"
+                                "to compute it.".format(mco_name))
+
+    def _find_kpc_by_computes(self, computes):
+        for kpc in self.key_performance_calculators:
+            if kpc.computes == computes:
+                return kpc
+
+        return None
+
+    def _find_mco_by_name(self, name):
+        for mco in self.multi_criteria_optimizers:
+            if mco.name == name:
+                return mco
+
+        return None
diff --git a/force_bdss/kpi/basic_key_performance_calculator.py b/force_bdss/kpi/basic.py
similarity index 66%
rename from force_bdss/kpi/basic_key_performance_calculator.py
rename to force_bdss/kpi/basic.py
index 3b7533e..6e0254a 100644
--- a/force_bdss/kpi/basic_key_performance_calculator.py
+++ b/force_bdss/kpi/basic.py
@@ -1,9 +1,11 @@
-from traits.api import provides, HasStrictTraits
+from traits.api import provides, HasStrictTraits, String
 
 from force_bdss.kpi.i_key_performance_calculator import IKeyPerformanceCalculator
 
 
 @provides(IKeyPerformanceCalculator)
-class BasicKeyPerformanceCalculator(HasStrictTraits):
+class Basic(HasStrictTraits):
+    computes = String("basic")
+
     def run(self, workflow):
         print("Computing basic key performance indicator, {}".format(workflow))
diff --git a/force_bdss/kpi/i_key_performance_calculator.py b/force_bdss/kpi/i_key_performance_calculator.py
index 8ad12ca..56b7205 100644
--- a/force_bdss/kpi/i_key_performance_calculator.py
+++ b/force_bdss/kpi/i_key_performance_calculator.py
@@ -1,6 +1,8 @@
-from traits.api import Interface
+from traits.api import Interface, String
 
 
 class IKeyPerformanceCalculator(Interface):
+    computes = String()
+
     def run(self):
         pass
diff --git a/force_bdss/kpi/key_performance_calculators_plugin.py b/force_bdss/kpi/key_performance_calculators_plugin.py
index 8122c80..a3b8f37 100644
--- a/force_bdss/kpi/key_performance_calculators_plugin.py
+++ b/force_bdss/kpi/key_performance_calculators_plugin.py
@@ -1,10 +1,14 @@
 from envisage.plugin import Plugin
 from traits.api import List
 
-from force_bdss.kpi.basic_key_performance_calculator import \
-    BasicKeyPerformanceCalculator
+from force_bdss.kpi.basic import \
+    Basic
 from force_bdss.kpi.i_key_performance_calculator import IKeyPerformanceCalculator
 
+from force_bdss.kpi.price import Price
+
+from force_bdss.kpi.viscosity import Viscosity
+
 
 class KeyPerformanceCalculatorsPlugin(Plugin):
 
@@ -16,4 +20,4 @@ class KeyPerformanceCalculatorsPlugin(Plugin):
     )
 
     def _key_performance_calculators_default(self):
-        return [BasicKeyPerformanceCalculator()]
+        return [Basic(), Viscosity(), Price()]
diff --git a/force_bdss/kpi/price.py b/force_bdss/kpi/price.py
new file mode 100644
index 0000000..86ebf36
--- /dev/null
+++ b/force_bdss/kpi/price.py
@@ -0,0 +1,11 @@
+from traits.api import provides, HasStrictTraits, String
+
+from force_bdss.kpi.i_key_performance_calculator import IKeyPerformanceCalculator
+
+
+@provides(IKeyPerformanceCalculator)
+class Price(HasStrictTraits):
+    computes = String("price")
+
+    def run(self, workflow):
+        print("Computing price")
diff --git a/force_bdss/kpi/viscosity.py b/force_bdss/kpi/viscosity.py
new file mode 100644
index 0000000..3c1fcb9
--- /dev/null
+++ b/force_bdss/kpi/viscosity.py
@@ -0,0 +1,11 @@
+from traits.api import provides, HasStrictTraits, String
+
+from force_bdss.kpi.i_key_performance_calculator import IKeyPerformanceCalculator
+
+
+@provides(IKeyPerformanceCalculator)
+class Viscosity(HasStrictTraits):
+    computes = String("viscosity")
+
+    def run(self, workflow):
+        print("Computing viscosity")
diff --git a/force_bdss/mco/basic_multi_criteria_optimizer.py b/force_bdss/mco/basic.py
similarity index 62%
rename from force_bdss/mco/basic_multi_criteria_optimizer.py
rename to force_bdss/mco/basic.py
index 2fc3a35..2e29c3b 100644
--- a/force_bdss/mco/basic_multi_criteria_optimizer.py
+++ b/force_bdss/mco/basic.py
@@ -1,16 +1,16 @@
 import subprocess
 import sys
 
-from traits.api import provides, HasStrictTraits
+from traits.api import provides, HasStrictTraits, String
 
 from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
 
 
 @provides(IMultiCriteriaOptimizer)
-class BasicMultiCriteriaOptimizer(HasStrictTraits):
-    name = "basic"
+class Basic(HasStrictTraits):
+    name = String("basic")
 
     def run(self, application):
-        print("Basic multicriteria optimizer in action")
+        print("Running Basic optimizer")
         subprocess.check_call([sys.argv[0], "--evaluate",
                                application.workflow_filepath])
diff --git a/force_bdss/mco/dakota.py b/force_bdss/mco/dakota.py
new file mode 100644
index 0000000..b046b11
--- /dev/null
+++ b/force_bdss/mco/dakota.py
@@ -0,0 +1,17 @@
+import subprocess
+
+import sys
+
+from traits.api import provides, HasStrictTraits, String
+
+from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
+
+
+@provides(IMultiCriteriaOptimizer)
+class Dakota(HasStrictTraits):
+    name = String("dakota")
+
+    def run(self, application):
+        print("Running dakota optimizer")
+        subprocess.check_call([sys.argv[0], "--evaluate",
+                               application.workflow_filepath])
diff --git a/force_bdss/mco/multi_criteria_optimizers_plugin.py b/force_bdss/mco/multi_criteria_optimizers_plugin.py
index 42d6333..79e3f30 100644
--- a/force_bdss/mco/multi_criteria_optimizers_plugin.py
+++ b/force_bdss/mco/multi_criteria_optimizers_plugin.py
@@ -1,8 +1,8 @@
 from envisage.plugin import Plugin
 from traits.api import List
 
-from force_bdss.mco.basic_multi_criteria_optimizer import \
-    BasicMultiCriteriaOptimizer
+from force_bdss.mco.basic import Basic
+from force_bdss.mco.dakota import Dakota
 from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
 
 
@@ -15,4 +15,4 @@ class MultiCriteriaOptimizersPlugin(Plugin):
     )
 
     def _multi_criteria_optimizers_default(self):
-        return [BasicMultiCriteriaOptimizer()]
+        return [Basic(), Dakota()]
diff --git a/force_bdss/workspecs/multi_criteria_optimization.py b/force_bdss/workspecs/multi_criteria_optimization.py
index 3433730..9e5e315 100644
--- a/force_bdss/workspecs/multi_criteria_optimization.py
+++ b/force_bdss/workspecs/multi_criteria_optimization.py
@@ -2,7 +2,7 @@ from traits.api import HasStrictTraits, String
 
 
 class MultiCriteriaOptimization(HasStrictTraits):
-    type = String
+    name = String()
 
     @classmethod
     def from_json(cls, json_data):
diff --git a/force_bdss/workspecs/workflow.py b/force_bdss/workspecs/workflow.py
index 6ff7cf7..934c778 100644
--- a/force_bdss/workspecs/workflow.py
+++ b/force_bdss/workspecs/workflow.py
@@ -1,4 +1,4 @@
-from traits.api import HasStrictTraits, Instance, String
+from traits.api import HasStrictTraits, Instance, String, List
 
 from .multi_criteria_optimization import MultiCriteriaOptimization
 
@@ -6,13 +6,15 @@ from .multi_criteria_optimization import MultiCriteriaOptimization
 class Workflow(HasStrictTraits):
     name = String()
     multi_criteria_optimization = Instance(MultiCriteriaOptimization)
+    key_performance_indicators = List(String)
 
     @classmethod
     def from_json(cls, json_data):
         self = cls(
             multi_criteria_optimization=MultiCriteriaOptimization.from_json(
                     json_data["multi_criteria_optimization"]
-                )
+            ),
+            key_performance_indicators=json_data["key_performance_indicators"]
             )
 
         return self
-- 
GitLab