Skip to content
Snippets Groups Projects
Commit fa121b2c authored by Stefano Borini's avatar Stefano Borini Committed by GitHub
Browse files

Merge pull request #2 from force-h2020/prototype-1

Prototype using envisage plugins
parents 01d5fcf9 bee0441c
No related branches found
No related tags found
No related merge requests found
Showing
with 286 additions and 1 deletion
[flake8]
exclude = build/*,venv/*,doc/source/*,tests/utils.py,braindump/*
language: c
cache:
directories:
- "$HOME/.cache"
- "$HOME/.ccache"
before_install:
- ccache -s
- export PATH=/usr/lib/ccache:${PATH}
- wget https://package-data.enthought.com/edm/rh5_x86_64/1.4/edm_1.4.1_linux_x86_64.sh && bash ./edm_1.4.1_linux_x86_64.sh -b -p $HOME
- export PATH=${HOME}/edm/bin:${PATH}
- edm environments create --version 3.5 force
- . $HOME/.edm/envs/force/bin/activate
- cat requirements/edm_requirements.txt | grep -v "^#" | while read line; do edm install -y `echo $line | awk '{print $1"=="$2}'`; done
install:
- pip install -r requirements/requirements.txt
- pip install -e .
script:
- pip install -r requirements/dev_requirements.txt
- flake8 .
FORCE BDSS
----------
This repository contains the implementation of the Business Decision System. It is implemented
under the FORCE project (Horizon 2020/NMBP-23-2016/721027).
from force import *
from force_bdss import *
wf=Workflow()
wf.set_mco(Dakota())
......
{
"multi_criteria_optimization": {
"name": "basic"
},
"key_performance_indicators": [
"viscosity", "price"
]
}
File moved
import json
from envisage.api import Application
from traits.api import Unicode, Bool, Instance
from force_bdss.workspecs.workflow import Workflow
class BDSSApplication(Application):
"""Main application for the BDSS.
"""
id = "force_bdss.bdss_application"
#: The path of the workflow file to open
workflow_filepath = Unicode()
#: Deserialized content of the workflow file.
workflow = Instance(Workflow)
#: This flags signals to the application not to execute and orchestrate
#: the MCO, but instead to perform a single evaluation under the
#: coordination of the MCO itself. See design notes for more details.
evaluate = Bool()
def _workflow_default(self):
with open(self.workflow_filepath) as f:
return Workflow.from_json(json.load(f))
import click
from envisage.core_plugin import CorePlugin
from force_bdss.bdss_application import BDSSApplication
from force_bdss.core_mco_driver import CoreMCODriver
from force_bdss.kpi.key_performance_calculators_plugin import \
KeyPerformanceCalculatorsPlugin
from force_bdss.mco.multi_criteria_optimizers_plugin import \
MultiCriteriaOptimizersPlugin
@click.command()
@click.option("--evaluate", is_flag=True)
@click.argument('workflow_filepath', type=click.Path(exists=True))
def run(evaluate, workflow_filepath):
plugins = [
CorePlugin(),
CoreMCODriver(),
KeyPerformanceCalculatorsPlugin(),
MultiCriteriaOptimizersPlugin(),
]
application = BDSSApplication(
plugins=plugins,
evaluate=evaluate,
workflow_filepath=workflow_filepath
)
application.run()
from envisage.extension_point import ExtensionPoint
from envisage.plugin import Plugin
from traits.has_traits import on_trait_change
from traits.trait_types import List
from force_bdss.kpi.i_key_performance_calculator import (
IKeyPerformanceCalculator)
from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
class CoreMCODriver(Plugin):
"""Main plugin that handles the execution of the MCO
or the evaluation.
"""
# Note: we are forced to declare these extensions points here instead
# of the application object, and this is why we have to use this plugin.
# It is a workaround to an envisage bug that does not find the extension
# points if declared on the application.
#: A List of the available Multi Criteria Optimizers.
#: This will be populated by MCO plugins.
multi_criteria_optimizers = ExtensionPoint(
List(IMultiCriteriaOptimizer),
id='force_bdss.multi_criteria_optimizers')
#: A list of the available Key Performance Indicator calculators.
#: It will be populated by plugins.
key_performance_calculators = ExtensionPoint(
List(IKeyPerformanceCalculator),
id='force_bdss.key_performance_calculators')
@on_trait_change("application:started")
def application_started(self):
workflow = self.application.workflow
if self.application.evaluate:
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:
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
from traits.api import provides, HasStrictTraits, String
from force_bdss.kpi.i_key_performance_calculator import (
IKeyPerformanceCalculator)
@provides(IKeyPerformanceCalculator)
class Basic(HasStrictTraits):
computes = String("basic")
def run(self, workflow):
print("Computing basic key performance indicator, {}".format(workflow))
from traits.api import Interface, String
class IKeyPerformanceCalculator(Interface):
computes = String()
def run(self):
pass
from envisage.plugin import Plugin
from traits.api import List
from force_bdss.kpi.i_key_performance_calculator import (
IKeyPerformanceCalculator)
from force_bdss.kpi.basic import Basic
from force_bdss.kpi.price import Price
from force_bdss.kpi.viscosity import Viscosity
class KeyPerformanceCalculatorsPlugin(Plugin):
id = "force_bdss.key_performance_calculators_plugin"
key_performance_calculators = List(
IKeyPerformanceCalculator,
contributes_to='force_bdss.key_performance_calculators'
)
def _key_performance_calculators_default(self):
return [Basic(), Viscosity(), Price()]
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")
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")
import subprocess
import sys
from traits.api import provides, HasStrictTraits, String
from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
@provides(IMultiCriteriaOptimizer)
class Basic(HasStrictTraits):
name = String("basic")
def run(self, application):
print("Running Basic optimizer")
subprocess.check_call([sys.argv[0], "--evaluate",
application.workflow_filepath])
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])
from traits.api import Interface, String
class IMultiCriteriaOptimizer(Interface):
name = String()
def run(self, application):
pass
from envisage.plugin import Plugin
from traits.api import List
from force_bdss.mco.basic import Basic
from force_bdss.mco.dakota import Dakota
from force_bdss.mco.i_multi_criteria_optimizers import IMultiCriteriaOptimizer
class MultiCriteriaOptimizersPlugin(Plugin):
id = "force_bdss.multi_criteria_optimizers_plugin"
multi_criteria_optimizers = List(
IMultiCriteriaOptimizer,
contributes_to='force_bdss.multi_criteria_optimizers'
)
def _multi_criteria_optimizers_default(self):
return [Basic(), Dakota()]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment