From 5958e4e271b4f55aee6708de462e146e84512c67 Mon Sep 17 00:00:00 2001
From: Stefano Borini <sborini@enthought.com>
Date: Thu, 27 Jul 2017 17:31:13 +0100
Subject: [PATCH] Removing application and model from bundles

---
 force_bdss/core_evaluation_driver.py             |  8 +++-----
 force_bdss/core_mco_driver.py                    |  4 ++--
 .../dummy/dummy_dakota/dakota_bundle.py          |  8 ++++----
 .../dummy/dummy_dakota/dakota_communicator.py    |  8 ++++----
 .../dummy/dummy_dakota/dakota_optimizer.py       |  8 +++++---
 .../tests/test_dakota_communicator.py            |  5 ++---
 force_bdss/core_plugins/dummy/dummy_plugin.py    | 10 +++++-----
 .../data_sources/base_data_source_bundle.py      |  9 ++++++++-
 force_bdss/kpi/base_kpi_calculator_bundle.py     |  9 ++++++++-
 force_bdss/mco/base_mco.py                       | 12 ++----------
 force_bdss/mco/base_mco_bundle.py                | 16 +++++++++++-----
 force_bdss/mco/base_mco_communicator.py          | 12 +++---------
 force_bdss/mco/i_mco_bundle.py                   |  4 ++--
 force_bdss/mco/tests/test_base_mco.py            | 11 ++---------
 .../mco/tests/test_base_mco_communicator.py      | 13 +++----------
 15 files changed, 64 insertions(+), 73 deletions(-)

diff --git a/force_bdss/core_evaluation_driver.py b/force_bdss/core_evaluation_driver.py
index 61dac3e..ebe24cf 100644
--- a/force_bdss/core_evaluation_driver.py
+++ b/force_bdss/core_evaluation_driver.py
@@ -25,11 +25,9 @@ class CoreEvaluationDriver(BaseCoreDriver):
 
         mco_model = workflow.mco
         mco_bundle = mco_model.bundle
-        mco_communicator = mco_bundle.create_communicator(
-            self.application,
-            mco_model)
+        mco_communicator = mco_bundle.create_communicator()
 
-        parameters = mco_communicator.receive_from_mco()
+        parameters = mco_communicator.receive_from_mco(mco_model)
 
         ds_results = []
         for ds_model in workflow.data_sources:
@@ -45,4 +43,4 @@ class CoreEvaluationDriver(BaseCoreDriver):
                 self.application, kpic_model)
             kpi_results.append(kpi_calculator.run(ds_results))
 
-        mco_communicator.send_to_mco(kpi_results)
+        mco_communicator.send_to_mco(mco_model, kpi_results)
diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index 07973cc..0affb65 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -26,5 +26,5 @@ class CoreMCODriver(BaseCoreDriver):
 
         mco_model = workflow.mco
         mco_bundle = mco_model.bundle
-        mco = mco_bundle.create_optimizer(self.application, mco_model)
-        mco.run()
+        mco = mco_bundle.create_optimizer()
+        mco.run(mco_model)
diff --git a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_bundle.py b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_bundle.py
index 7fda192..925a127 100644
--- a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_bundle.py
+++ b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_bundle.py
@@ -16,8 +16,8 @@ class DummyDakotaBundle(BaseMCOBundle):
             model_data = {}
         return DummyDakotaModel(self, **model_data)
 
-    def create_optimizer(self, application, model):
-        return DummyDakotaOptimizer(self, application, model)
+    def create_optimizer(self):
+        return DummyDakotaOptimizer(self)
 
-    def create_communicator(self, application, model):
-        return DummyDakotaCommunicator(self, application, model)
+    def create_communicator(self):
+        return DummyDakotaCommunicator(self)
diff --git a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_communicator.py b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_communicator.py
index 9f9d441..d5b53d9 100644
--- a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_communicator.py
+++ b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_communicator.py
@@ -5,11 +5,11 @@ from force_bdss.api import DataSourceParameters, BaseMCOCommunicator
 
 
 class DummyDakotaCommunicator(BaseMCOCommunicator):
-    def receive_from_mco(self):
+    def receive_from_mco(self, model):
         data = sys.stdin.read()
         values = list(map(float, data.split()))
-        value_names = [p.value_name for p in self.model.parameters]
-        value_types = [p.value_type for p in self.model.parameters]
+        value_names = [p.value_name for p in model.parameters]
+        value_types = [p.value_type for p in model.parameters]
 
         return DataSourceParameters(
             value_names=value_names,
@@ -17,7 +17,7 @@ class DummyDakotaCommunicator(BaseMCOCommunicator):
             values=numpy.array(values)
         )
 
-    def send_to_mco(self, kpi_results):
+    def send_to_mco(self, model, kpi_results):
         data = " ".join(
             [" ".join(list(map(str, r.values.tolist()))) for r in kpi_results]
         )
diff --git a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py
index b493853..2114efe 100644
--- a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py
+++ b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py
@@ -15,8 +15,8 @@ def rotated_range(start, stop, starting_value):
 
 
 class DummyDakotaOptimizer(BaseMCO):
-    def run(self):
-        parameters = self.model.parameters
+    def run(self, model):
+        parameters = model.parameters
 
         values = []
         for p in parameters:
@@ -28,11 +28,13 @@ class DummyDakotaOptimizer(BaseMCO):
 
         value_iterator = itertools.product(*values)
 
+        application = self.bundle.plugin.application
+
         for value in value_iterator:
             ps = subprocess.Popen(
                 [sys.argv[0],
                  "--evaluate",
-                 self.application.workflow_filepath],
+                 application.workflow_filepath],
                 stdout=subprocess.PIPE,
                 stdin=subprocess.PIPE)
 
diff --git a/force_bdss/core_plugins/dummy/dummy_dakota/tests/test_dakota_communicator.py b/force_bdss/core_plugins/dummy/dummy_dakota/tests/test_dakota_communicator.py
index a17b59d..cacf0ad 100644
--- a/force_bdss/core_plugins/dummy/dummy_dakota/tests/test_dakota_communicator.py
+++ b/force_bdss/core_plugins/dummy/dummy_dakota/tests/test_dakota_communicator.py
@@ -19,18 +19,17 @@ except ImportError:
 class TestDakotaCommunicator(unittest.TestCase):
     def test_receive_from_mco(self):
         bundle = DummyDakotaBundle()
-        mock_application = mock.Mock(spec=BDSSApplication)
         mock_parameter_factory = mock.Mock(spec=BaseMCOParameterFactory)
         model = bundle.create_model()
         model.parameters = [
             RangedMCOParameter(mock_parameter_factory)
         ]
-        comm = bundle.create_communicator(mock_application, model)
+        comm = bundle.create_communicator()
 
         with mock.patch("sys.stdin") as stdin:
             stdin.read.return_value = "1"
 
-            data = comm.receive_from_mco()
+            data = comm.receive_from_mco(model)
             self.assertIsInstance(data, DataSourceParameters)
             self.assertEqual(len(data.value_names), 1)
             self.assertEqual(len(data.value_types), 1)
diff --git a/force_bdss/core_plugins/dummy/dummy_plugin.py b/force_bdss/core_plugins/dummy/dummy_plugin.py
index 3eca5b3..b62845d 100644
--- a/force_bdss/core_plugins/dummy/dummy_plugin.py
+++ b/force_bdss/core_plugins/dummy/dummy_plugin.py
@@ -10,12 +10,12 @@ from .dummy_kpi_calculator.dummy_kpi_calculator_bundle import (
 
 class DummyPlugin(BaseExtensionPlugin):
     def _data_source_bundles_default(self):
-        return [DummyDataSourceBundle(),
-                CSVExtractorBundle()]
+        return [DummyDataSourceBundle(self),
+                CSVExtractorBundle(self)]
 
     def _mco_bundles_default(self):
-        return [DummyDakotaBundle()]
+        return [DummyDakotaBundle(self)]
 
     def _kpi_calculator_bundles_default(self):
-        return [DummyKPICalculatorBundle(),
-                KPIAdderBundle()]
+        return [DummyKPICalculatorBundle(self),
+                KPIAdderBundle(self)]
diff --git a/force_bdss/data_sources/base_data_source_bundle.py b/force_bdss/data_sources/base_data_source_bundle.py
index ab53763..422de86 100644
--- a/force_bdss/data_sources/base_data_source_bundle.py
+++ b/force_bdss/data_sources/base_data_source_bundle.py
@@ -1,5 +1,6 @@
 import abc
-from traits.api import ABCHasStrictTraits, provides, String
+from traits.api import ABCHasStrictTraits, provides, String, Instance
+from envisage.plugin import Plugin
 
 from .i_data_source_bundle import IDataSourceBundle
 
@@ -18,6 +19,12 @@ class BaseDataSourceBundle(ABCHasStrictTraits):
     #: A human readable name of the bundle. Spaces allowed
     name = String()
 
+    plugin = Instance(Plugin)
+
+    def __init__(self, plugin, *args, **kwargs):
+        self.plugin = plugin
+        super(BaseDataSourceBundle, self).__init__(*args, **kwargs)
+
     @abc.abstractmethod
     def create_data_source(self, application, model):
         """Factory method.
diff --git a/force_bdss/kpi/base_kpi_calculator_bundle.py b/force_bdss/kpi/base_kpi_calculator_bundle.py
index 5ae4063..756b70d 100644
--- a/force_bdss/kpi/base_kpi_calculator_bundle.py
+++ b/force_bdss/kpi/base_kpi_calculator_bundle.py
@@ -1,5 +1,6 @@
 import abc
-from traits.api import ABCHasStrictTraits, provides, String
+from envisage.plugin import Plugin
+from traits.api import ABCHasStrictTraits, provides, String, Instance
 
 from .i_kpi_calculator_bundle import IKPICalculatorBundle
 
@@ -19,6 +20,12 @@ class BaseKPICalculatorBundle(ABCHasStrictTraits):
     #: A UI friendly name for the bundle. Can contain spaces.
     name = String()
 
+    plugin = Instance(Plugin)
+
+    def __init__(self, plugin, *args, **kwargs):
+        self.plugin = plugin
+        super(BaseKPICalculatorBundle, self).__init__(*args, **kwargs)
+
     @abc.abstractmethod
     def create_kpi_calculator(self, application, model):
         """Factory method.
diff --git a/force_bdss/mco/base_mco.py b/force_bdss/mco/base_mco.py
index a562f1c..30d1626 100644
--- a/force_bdss/mco/base_mco.py
+++ b/force_bdss/mco/base_mco.py
@@ -2,8 +2,6 @@ import abc
 
 from traits.api import ABCHasStrictTraits, Instance
 
-from ..bdss_application import BDSSApplication
-from .base_mco_model import BaseMCOModel
 from .i_mco_bundle import IMCOBundle
 
 
@@ -14,18 +12,12 @@ class BaseMCO(ABCHasStrictTraits):
     """
     #: A reference to the bundle
     bundle = Instance(IMCOBundle)
-    #: A reference to the application
-    application = Instance(BDSSApplication)
-    #: A reference to the model class
-    model = Instance(BaseMCOModel)
 
-    def __init__(self, bundle, application, model, *args, **kwargs):
+    def __init__(self, bundle, *args, **kwargs):
         self.bundle = bundle
-        self.application = application
-        self.model = model
         super(BaseMCO, self).__init__(*args, **kwargs)
 
     @abc.abstractmethod
-    def run(self):
+    def run(self, model):
         """Reimplement this method to perform the MCO operations."""
         pass
diff --git a/force_bdss/mco/base_mco_bundle.py b/force_bdss/mco/base_mco_bundle.py
index 8eb366d..2fb6fbb 100644
--- a/force_bdss/mco/base_mco_bundle.py
+++ b/force_bdss/mco/base_mco_bundle.py
@@ -1,9 +1,9 @@
 import abc
 
-from traits.api import ABCHasStrictTraits, String
-from traits.has_traits import provides
+from traits.api import ABCHasStrictTraits, String, provides, Instance
+from envisage.plugin import Plugin
 
-from force_bdss.mco.i_mco_bundle import IMCOBundle
+from .i_mco_bundle import IMCOBundle
 
 
 @provides(IMCOBundle)
@@ -19,8 +19,14 @@ class BaseMCOBundle(ABCHasStrictTraits):
     #: A user friendly name of the bundle. Spaces allowed.
     name = String()
 
+    plugin = Instance(Plugin)
+
+    def __init__(self, plugin, *args, **kwargs):
+        self.plugin = plugin
+        super(BaseMCOBundle, self).__init__(*args, **kwargs)
+
     @abc.abstractmethod
-    def create_optimizer(self, application, model):
+    def create_optimizer(self):
         """Factory method.
         Creates the optimizer with the given application
         and model and returns it to the caller.
@@ -60,7 +66,7 @@ class BaseMCOBundle(ABCHasStrictTraits):
         """
 
     @abc.abstractmethod
-    def create_communicator(self, application, model):
+    def create_communicator(self):
         """Factory method. Returns the communicator class that allows
         exchange between the MCO and the evaluator code.
 
diff --git a/force_bdss/mco/base_mco_communicator.py b/force_bdss/mco/base_mco_communicator.py
index 873da9f..aaa539b 100644
--- a/force_bdss/mco/base_mco_communicator.py
+++ b/force_bdss/mco/base_mco_communicator.py
@@ -20,18 +20,12 @@ class BaseMCOCommunicator(ABCHasStrictTraits):
     """
     #: A reference to the bundle
     bundle = Instance(IMCOBundle)
-    #: A reference to the application
-    application = Instance(BDSSApplication)
-    #: A reference to the model class
-    model = Instance(BaseMCOModel)
 
-    def __init__(self, bundle, application, model):
+    def __init__(self, bundle):
         self.bundle = bundle
-        self.application = application
-        self.model = model
 
     @abc.abstractmethod
-    def receive_from_mco(self):
+    def receive_from_mco(self, model):
         """
         Receives the parameters from the MCO.
         The conversion is specific to the format of the communication
@@ -48,7 +42,7 @@ class BaseMCOCommunicator(ABCHasStrictTraits):
         """
 
     @abc.abstractmethod
-    def send_to_mco(self, kpi_results):
+    def send_to_mco(self, model, kpi_results):
         """Send the KPI results from the evaluation to the MCO
         Must be reimplemented to perform the conversion between the
         two formats. This is of course dependent on the specifics of the
diff --git a/force_bdss/mco/i_mco_bundle.py b/force_bdss/mco/i_mco_bundle.py
index dd7e1b9..3e0c199 100644
--- a/force_bdss/mco/i_mco_bundle.py
+++ b/force_bdss/mco/i_mco_bundle.py
@@ -9,11 +9,11 @@ class IMCOBundle(Interface):
 
     name = String()
 
-    def create_optimizer(self, application, model):
+    def create_optimizer(self):
         pass
 
     def create_model(self, model_data=None):
         pass
 
-    def create_communicator(self, application, model):
+    def create_communicator(self):
         pass
diff --git a/force_bdss/mco/tests/test_base_mco.py b/force_bdss/mco/tests/test_base_mco.py
index f228f32..e5e9130 100644
--- a/force_bdss/mco/tests/test_base_mco.py
+++ b/force_bdss/mco/tests/test_base_mco.py
@@ -1,6 +1,5 @@
 import unittest
 
-from force_bdss.mco.base_mco_model import BaseMCOModel
 from force_bdss.mco.base_mco import BaseMCO
 from force_bdss.mco.i_mco_bundle import IMCOBundle
 
@@ -9,21 +8,15 @@ try:
 except ImportError:
     from unittest import mock
 
-from force_bdss.bdss_application import BDSSApplication
-
 
 class DummyMCO(BaseMCO):
-    def run(self, *args, **kwargs):
+    def run(self, model, *args, **kwargs):
         pass
 
 
 class TestBaseMultiCriteriaOptimizer(unittest.TestCase):
     def test_initialization(self):
         bundle = mock.Mock(spec=IMCOBundle)
-        application = mock.Mock(spec=BDSSApplication)
-        model = mock.Mock(spec=BaseMCOModel)
-        mco = DummyMCO(bundle, application, model)
+        mco = DummyMCO(bundle)
 
         self.assertEqual(mco.bundle, bundle)
-        self.assertEqual(mco.application, application)
-        self.assertEqual(mco.model, model)
diff --git a/force_bdss/mco/tests/test_base_mco_communicator.py b/force_bdss/mco/tests/test_base_mco_communicator.py
index 7cd7a25..5769444 100644
--- a/force_bdss/mco/tests/test_base_mco_communicator.py
+++ b/force_bdss/mco/tests/test_base_mco_communicator.py
@@ -1,7 +1,6 @@
 import unittest
 
 from force_bdss.mco.base_mco_communicator import BaseMCOCommunicator
-from force_bdss.mco.base_mco_model import BaseMCOModel
 from force_bdss.mco.i_mco_bundle import IMCOBundle
 
 try:
@@ -9,24 +8,18 @@ try:
 except ImportError:
     from unittest import mock
 
-from force_bdss.bdss_application import BDSSApplication
-
 
 class DummyMCOCommunicator(BaseMCOCommunicator):
-    def receive_from_mco(self):
+    def receive_from_mco(self, model):
         pass
 
-    def send_to_mco(self, kpi_results):
+    def send_to_mco(self, model, kpi_results):
         pass
 
 
 class TestBaseMCOCommunicator(unittest.TestCase):
     def test_initialization(self):
         bundle = mock.Mock(spec=IMCOBundle)
-        application = mock.Mock(spec=BDSSApplication)
-        model = mock.Mock(spec=BaseMCOModel)
-        mcocomm = DummyMCOCommunicator(bundle, application, model)
+        mcocomm = DummyMCOCommunicator(bundle)
 
         self.assertEqual(mcocomm.bundle, bundle)
-        self.assertEqual(mcocomm.application, application)
-        self.assertEqual(mcocomm.model, model)
-- 
GitLab