From ba1408345db258c36c3e2a5f87d2aa37973d3540 Mon Sep 17 00:00:00 2001 From: martinRenou <martin.renou@isae.fr> Date: Wed, 16 Aug 2017 17:16:29 +0100 Subject: [PATCH] Move the event handling in the core mco driver --- .../{mco/events.py => core_driver_events.py} | 14 ++++++----- force_bdss/core_mco_driver.py | 24 +++++++++++++++++-- .../dummy/dummy_dakota/dakota_optimizer.py | 14 ++++------- force_bdss/mco/base_mco.py | 18 +++----------- 4 files changed, 37 insertions(+), 33 deletions(-) rename force_bdss/{mco/events.py => core_driver_events.py} (57%) diff --git a/force_bdss/mco/events.py b/force_bdss/core_driver_events.py similarity index 57% rename from force_bdss/mco/events.py rename to force_bdss/core_driver_events.py index 216e1ef..b656bde 100644 --- a/force_bdss/mco/events.py +++ b/force_bdss/core_driver_events.py @@ -1,19 +1,21 @@ -from traits.api import HasStrictTraits, Tuple +from traits.api import HasStrictTraits, Tuple, Str -class BaseMCOEvent(HasStrictTraits): - """Base event for the MCO""" +class BaseDriverEvent(HasStrictTraits): + """Base event for the Driver""" -class MCOStartEvent(BaseMCOEvent): +class MCOStartEvent(BaseDriverEvent): """MCO should emit this event when the evaluation starts.""" + input_names = Str() + output_names = Str() -class MCOFinishEvent(BaseMCOEvent): +class MCOFinishEvent(BaseDriverEvent): """MCO should emit this event when the evaluation ends.""" -class MCOProgressEvent(BaseMCOEvent): +class MCOProgressEvent(BaseDriverEvent): """MCO should emit this event for every new evaluation that has been completed. It carries data about the evaluation, specifically the input data (MCO parameter values) and the resulting output (KPIs).""" diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py index e2678da..3048172 100644 --- a/force_bdss/core_mco_driver.py +++ b/force_bdss/core_mco_driver.py @@ -14,6 +14,7 @@ from .io.workflow_reader import ( InvalidVersionException, InvalidFileException ) +from .core_driver_events import MCOStartEvent, MCOFinishEvent, MCOProgressEvent log = logging.getLogger(__name__) CORE_MCO_DRIVER_ID = plugin_id("core", "CoreMCODriver") @@ -31,7 +32,9 @@ class CoreMCODriver(BaseCoreDriver): @on_trait_change("application:started") def application_started(self): + self._deliver_start_event() self.mco.run(self.workflow.mco) + self._deliver_event(MCOFinishEvent()) @on_trait_change("application:stopping") def application_stopping(self): @@ -50,8 +53,25 @@ class CoreMCODriver(BaseCoreDriver): mco_factory = mco_model.factory return mco_factory.create_optimizer() - @on_trait_change("mco:event") - def _handle_mco_event(self, event): + def _deliver_start_event(self): + output_names = [] + for kpi in self.workflow.kpi_calculators: + output_names.extend(kpi.output_slot_names) + + self._deliver_event(MCOStartEvent( + input_names=[p.name for p in self.workflow.mco.parameters], + output_names=output_names + )) + + @on_trait_change("mco:new_data") + def _deliver_progress_event(self, event): + self._deliver_event(MCOProgressEvent( + input=event['input'], + output=event['output'] + )) + + def _deliver_event(self, event): + """ Delivers an event to the listeners """ for listener in self.listeners[:]: try: listener.deliver(event) 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 9f9de5d..8ceddba 100644 --- a/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py +++ b/force_bdss/core_plugins/dummy/dummy_dakota/dakota_optimizer.py @@ -4,8 +4,6 @@ import itertools import collections from force_bdss.api import BaseMCO -from force_bdss.mco.events import MCOStartEvent, MCOFinishEvent, \ - MCOProgressEvent def rotated_range(start, stop, starting_value): @@ -18,8 +16,6 @@ def rotated_range(start, stop, starting_value): class DummyDakotaOptimizer(BaseMCO): def run(self, model): - self.notify_event(MCOStartEvent()) - parameters = model.parameters values = [] @@ -45,9 +41,7 @@ class DummyDakotaOptimizer(BaseMCO): out = ps.communicate( " ".join([str(v) for v in value]).encode("utf-8")) out_data = out[0].decode("utf-8").split() - self.notify_event(MCOProgressEvent( - input=tuple(value), - output=tuple(out_data), - )) - - self.notify_event(MCOFinishEvent()) + self.new_data = { + 'input': tuple(value), + 'output': tuple(out_data) + } diff --git a/force_bdss/mco/base_mco.py b/force_bdss/mco/base_mco.py index ae9d89b..2c576d2 100644 --- a/force_bdss/mco/base_mco.py +++ b/force_bdss/mco/base_mco.py @@ -17,6 +17,9 @@ class BaseMCO(ABCHasStrictTraits): #: Triggered when an event occurs. event = Event(BaseMCOEvent) + # Event triggered when the mco wants to send new data to listeners + new_data = Event() + def __init__(self, factory, *args, **kwargs): """Initializes the MCO. @@ -39,18 +42,3 @@ class BaseMCO(ABCHasStrictTraits): An instance of the model information, as created from create_model() """ - - def notify_event(self, event): - """Method based interface to deliver an event, instead of - assignment to traits. - - Sends the event, synchronously. When the routine returns, - listeners have been fully informed (they might, however, handle - the event asynchronously at their convenience) - - Parameters - ---------- - event: BaseMCOEvent - The event to deliver. - """ - self.event = event -- GitLab