diff --git a/examples/test_csv.json b/examples/test_csv.json index 721ceee308bde6478d91c6b8e59419a7dbc667ab..0fe50484a4c12813bcb882f6ea2d865aa9aac6bb 100644 --- a/examples/test_csv.json +++ b/examples/test_csv.json @@ -1,7 +1,9 @@ { "multi_criteria_optimizer": { "name": "dakota", - "model_data": {} + "model_data": { + "value_types": ["DUMMY"] + } }, "data_sources": [ { diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py index 54932bea10456e089627b8b339215ab492b352f2..b9e001e3a7e9f17bdc3328dfba785fb103b57bdb 100644 --- a/force_bdss/core_mco_driver.py +++ b/force_bdss/core_mco_driver.py @@ -41,68 +41,63 @@ class CoreMCODriver(Plugin): @on_trait_change("application:started") def application_started(self): workflow = self.application.workflow - if self.application.evaluate: - ds_results = [] - for requested_ds in workflow.data_sources: - ds_bundle = self._find_data_source_bundle_by_name( - requested_ds.name) - if ds_bundle: - ds_model = ds_bundle.create_model(requested_ds.model_data) - data_source = ds_bundle.create_data_source( - self.application, ds_model) - ds_results.append(data_source.run()) - else: - raise Exception("Requested data source {} but don't know " - "to find it.".format(requested_ds.name)) - - kpi_results = [] - for requested_kpic in workflow.kpi_calculators: - kpic_bundle = self._find_kpi_calculator_bundle_by_name( - requested_kpic.name) - if kpic_bundle: - ds_model = kpic_bundle.create_model( - requested_kpic.model_data) - kpi_calculator = kpic_bundle.create_data_source( - self.application, ds_model) - kpi_results.append(kpi_calculator.run(ds_results)) - else: - raise Exception( - "Requested kpi calculator {} but don't know " - "to find it.".format(requested_kpic.name)) - - print( - kpi_results[0].value_types, - kpi_results[0].values - ) - - else: - mco_data = workflow.multi_criteria_optimizer - mco_bundle = self._find_mco_bundle_by_name(mco_data.name) - if mco_bundle: - mco_model = mco_bundle.create_model(mco_data.model_data) - mco = mco_bundle.create_optimizer(self.application, mco_model) - mco.run() - else: - raise Exception("Requested MCO {} but it's not available" - "to compute it.".format(mco_data.name)) - - def _find_data_source_bundle_by_name(self, name): + + mco_data = workflow.multi_criteria_optimizer + mco_bundle = self._mco_bundle_by_name(mco_data.name) + mco_model = mco_bundle.create_model(mco_data.model_data) + mco = mco_bundle.create_optimizer(self.application, mco_model) + mco_communicator = mco_bundle.create_communicator( + self.application, + mco_model) + + if not self.application.evaluate: + mco.run() + return + + parameters = mco_communicator.receive_from_mco() + + ds_results = [] + for requested_ds in workflow.data_sources: + ds_bundle = self._data_source_bundle_by_name( + requested_ds.name) + ds_model = ds_bundle.create_model(requested_ds.model_data) + data_source = ds_bundle.create_data_source( + self.application, ds_model) + ds_results.append(data_source.run(parameters)) + + kpi_results = [] + for requested_kpic in workflow.kpi_calculators: + kpic_bundle = self._kpi_calculator_bundle_by_name( + requested_kpic.name) + ds_model = kpic_bundle.create_model( + requested_kpic.model_data) + kpi_calculator = kpic_bundle.create_data_source( + self.application, ds_model) + kpi_results.append(kpi_calculator.run(ds_results)) + + mco_communicator.send_to_mco(kpi_results) + + def _data_source_bundle_by_name(self, name): for ds in self.data_source_bundles: if ds.name == name: return ds - return None + raise Exception("Requested data source {} but don't know " + "to find it.".format(name)) - def _find_kpi_calculator_bundle_by_name(self, name): + def _kpi_calculator_bundle_by_name(self, name): for kpic in self.kpi_calculator_bundles: if kpic.name == name: return kpic - return None + raise Exception( + "Requested kpi calculator {} but don't know " + "to find it.".format(name)) - def _find_mco_bundle_by_name(self, name): + def _mco_bundle_by_name(self, name): for mco in self.mco_bundles: if mco.name == name: return mco - return None + raise Exception("Requested MCO {} but it's not available" + "to compute it.".format(mco_data.name)) diff --git a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py index 8cfb74e216012d83c3cb1a5bf819617f0ae4ae6b..7208153c407f679ab45978fa594415ce3cb7d67b 100644 --- a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py +++ b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_data_source.py @@ -5,7 +5,7 @@ from force_bdss.data_sources.data_source_result import DataSourceResult class CSVExtractorDataSource(BaseDataSource): - def run(self): + def run(self, parameters): with open(self.model.filename) as csvfile: reader = csv.reader(csvfile) for rowindex, row in enumerate(reader): @@ -17,7 +17,8 @@ class CSVExtractorDataSource(BaseDataSource): originator=self, value_types = [self.model.cuba_type], values=numpy.array( - float(row[self.model.column])).reshape(1,1) + parameters.values[0]+float( + row[self.model.column])).reshape(1,1) ) return None diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py b/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py index 12c34ab2e3502eb1edbbf0ef9952551da93b0db8..effed5735912edbfbd331e04a69aaf1dfce4b59e 100644 --- a/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py +++ b/force_bdss/core_plugins/test_mco/dakota/dakota_bundle.py @@ -1,6 +1,8 @@ from traits.has_traits import HasStrictTraits, provides from traits.trait_types import String +from force_bdss.core_plugins.test_mco.dakota.dakota_communicator import \ + DakotaCommunicator from force_bdss.mco.i_multi_criteria_optimizer_bundle import ( IMultiCriteriaOptimizerBundle) @@ -17,3 +19,6 @@ class DakotaBundle(HasStrictTraits): def create_optimizer(self, application, model): return DakotaOptimizer(self, application, model) + + def create_communicator(self, application, model): + return DakotaCommunicator(self, application, model) diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py b/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py new file mode 100644 index 0000000000000000000000000000000000000000..ae9677fdf72b409ef79956c3852163da4ba9d35c --- /dev/null +++ b/force_bdss/core_plugins/test_mco/dakota/dakota_communicator.py @@ -0,0 +1,27 @@ +import sys +import numpy + +from force_bdss.data_sources.data_source_parameters import DataSourceParameters +from force_bdss.mco.base_mco_communicator import BaseMCOCommunicator + + +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)) + + return DataSourceParameters( + value_types=value_types, + values=numpy.array(values) + ) + + def send_to_mco(self, kpi_results): + data = " ".join( + [" ".join(list(map(str, r.values.tolist()))) for r in kpi_results] + ) + sys.stdout.write(data) diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_model.py b/force_bdss/core_plugins/test_mco/dakota/dakota_model.py index ed6ff342dfdd8c2ee8742ba32f86808cb8f82582..fe7edcdc6cb3411945de29cdec4806e5cecce88f 100644 --- a/force_bdss/core_plugins/test_mco/dakota/dakota_model.py +++ b/force_bdss/core_plugins/test_mco/dakota/dakota_model.py @@ -1,7 +1,9 @@ -from traits.api import HasStrictTraits +from traits.api import HasStrictTraits, List, String class DakotaModel(HasStrictTraits): + value_types = List(String) + @classmethod def from_json(cls, model_data): - return cls() + return cls(value_types=model_data["value_types"]) diff --git a/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py b/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py index 0f8f064cc985e2afdb6fc99765f42596ae49cece..edd177d6e863c41a4e6b378926ceff92a5b3c15a 100644 --- a/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py +++ b/force_bdss/core_plugins/test_mco/dakota/dakota_optimizer.py @@ -10,5 +10,13 @@ from force_bdss.mco.base_multi_criteria_optimizer import ( class DakotaOptimizer(BaseMultiCriteriaOptimizer): def run(self): print("Running dakota optimizer") - subprocess.check_call([sys.argv[0], "--evaluate", - self.application.workflow_filepath]) + for initial_value in range(10): + ps = subprocess.Popen( + [sys.argv[0], + "--evaluate", + self.application.workflow_filepath], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + + out = ps.communicate("{}".format(initial_value).encode("utf-8")) + print("{}: {}".format(initial_value, out[0].decode("utf-8"))) diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py index 469ed8b902cc9d237139bf6b53ef6e2a952a20e8..e8eec36d78660d9aab8eb24f2e140392d807a05e 100644 --- a/force_bdss/data_sources/base_data_source.py +++ b/force_bdss/data_sources/base_data_source.py @@ -13,7 +13,7 @@ class BaseDataSource(six.with_metaclass(abc.ABCMeta)): return self.bundle.name @abc.abstractmethod - def run(self): + def run(self, parameters): """Executes the data source evaluation/fetching and returns the list of results as a DataSourceResult instance.""" pass diff --git a/force_bdss/data_sources/data_source_parameters.py b/force_bdss/data_sources/data_source_parameters.py new file mode 100644 index 0000000000000000000000000000000000000000..c45915dd1f056873e96e9e957753a90409c3d215 --- /dev/null +++ b/force_bdss/data_sources/data_source_parameters.py @@ -0,0 +1,6 @@ +from traits.api import HasStrictTraits, Array, List, String + + +class DataSourceParameters(HasStrictTraits): + value_types = List(String) + values = Array(shape=(None,)) diff --git a/force_bdss/mco/base_mco_communicator.py b/force_bdss/mco/base_mco_communicator.py new file mode 100644 index 0000000000000000000000000000000000000000..308903166cdebdbf8dcee705ff4089fb626e3639 --- /dev/null +++ b/force_bdss/mco/base_mco_communicator.py @@ -0,0 +1,17 @@ +import abc +import six + + +class BaseMCOCommunicator(six.with_metaclass(abc.ABCMeta)): + def __init__(self, bundle, application, model): + self.bundle = bundle + self.application = application + self.model = model + + @abc.abstractmethod + def receive_from_mco(self): + pass + + @abc.abstractmethod + def send_to_mco(self): + pass diff --git a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py index 33c9a37c78a932045132609ef4f3a455b706ba22..f84cca5379b0bacb7ca11365ac84777307015cdb 100644 --- a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py +++ b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py @@ -9,3 +9,6 @@ class IMultiCriteriaOptimizerBundle(Interface): def create_model(self, model_data): pass + + def create_communicator(self, model_data): + pass