diff --git a/force_bdss/core/slot.py b/force_bdss/core/slot.py new file mode 100644 index 0000000000000000000000000000000000000000..22182759c6be5ab0a05833916b7e03fbfdcbb09b --- /dev/null +++ b/force_bdss/core/slot.py @@ -0,0 +1,11 @@ +from traits.api import HasStrictTraits, String + + +class Slot(HasStrictTraits): + """Describes an input or output slot in the DataSource or + KPICalculator""" + #: A textual description of the slot + description = String("No description") + + #: The CUBA key of the slot + type = String() diff --git a/force_bdss/core/tests/test_slot.py b/force_bdss/core/tests/test_slot.py new file mode 100644 index 0000000000000000000000000000000000000000..b6c687e596eb92e7b6a8f256a720ff9528a95fa4 --- /dev/null +++ b/force_bdss/core/tests/test_slot.py @@ -0,0 +1,10 @@ +import unittest + +from force_bdss.core.slot import Slot + + +class TestSlot(unittest.TestCase): + def test_initialization(self): + slot = Slot() + self.assertEqual(slot.type, "") + self.assertEqual(slot.description, "No description") diff --git a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py index 471f3ac6c18592ed248d6a18d12559bdc6359340..36f729720f8933fe6121d1c820bcb6f09ea662f0 100644 --- a/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py +++ b/force_bdss/core_plugins/dummy/csv_extractor/csv_extractor_data_source.py @@ -1,5 +1,6 @@ import csv from force_bdss.api import BaseDataSource, DataValue +from force_bdss.core.slot import Slot class CSVExtractorDataSource(BaseDataSource): @@ -20,3 +21,11 @@ class CSVExtractorDataSource(BaseDataSource): break raise IndexError("Could not find specified data.") + + def slots(self, model): + return ( + (), + ( + Slot(type=model.cuba_type), + ) + ) diff --git a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py index 03c36de2f42e17926d2069a6b7723e46b986980e..ac4dc61f73b6c3d9f8609187695242e852492172 100644 --- a/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py +++ b/force_bdss/core_plugins/dummy/dummy_data_source/dummy_data_source.py @@ -4,3 +4,6 @@ from force_bdss.api import BaseDataSource class DummyDataSource(BaseDataSource): def run(self, model, parameters): return parameters + + def slots(self, model): + return (), () diff --git a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py index bd104731babee708112797eebe991a1ca732504e..3e035cb77ed03c4ccd01960978eca8222f7a26c8 100644 --- a/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py +++ b/force_bdss/core_plugins/dummy/dummy_kpi_calculator/dummy_kpi_calculator.py @@ -4,3 +4,6 @@ from force_bdss.api import BaseKPICalculator class DummyKPICalculator(BaseKPICalculator): def run(self, model, data_source_results): return data_source_results + + def slots(self, model): + return (), () diff --git a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py index 94128b30519bf6bcac5fc63e0f418cd758ea7f80..ff4b7ce8da3161864c33a486f7b1413bd14da599 100644 --- a/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py +++ b/force_bdss/core_plugins/dummy/kpi_adder/kpi_adder_calculator.py @@ -1,4 +1,5 @@ from force_bdss.api import BaseKPICalculator, DataValue +from force_bdss.core.slot import Slot class KPIAdderCalculator(BaseKPICalculator): @@ -16,3 +17,13 @@ class KPIAdderCalculator(BaseKPICalculator): type=model.cuba_type_out, value=sum )] + + def slots(self, model): + return ( + ( + Slot(type=model.cuba_type_in), + ), + ( + Slot(type=model.cuba_type_out), + ) + ) diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py index e0283b5da75b9d2fb7a42f69049c54b482d4f00d..be9fb39f4f338fb5cca32664ac3a4970596d0f4b 100644 --- a/force_bdss/data_sources/base_data_source.py +++ b/force_bdss/data_sources/base_data_source.py @@ -55,8 +55,14 @@ class BaseDataSource(ABCHasStrictTraits): Returns ------- - list[tuple, tuple] - A list containing two tuples, the first element is the input slots, - the second element is the output slots. Each slot must be an - instance of the Slot class. + (input_slots, output_slots): tuple[tuple, tuple] + A tuple containing two tuples. + The first element is the input slots, the second element is + the output slots. Each slot must be an instance of the Slot class. + It is possible for each of the two inside tuples to be empty. + The case of an empty input slot is common: the DataSource does + not need any information from the MCO to operate. + The case of an empty output slot is uncommon, but supported: + the DataSource does not produce any output and is therefore + useless. """ diff --git a/force_bdss/data_sources/tests/test_base_data_source.py b/force_bdss/data_sources/tests/test_base_data_source.py index 810b5f63805914b3b7c872d983eaaae022bbc471..a4de04182cb54cfd711cbf18ba7517ab2149151e 100644 --- a/force_bdss/data_sources/tests/test_base_data_source.py +++ b/force_bdss/data_sources/tests/test_base_data_source.py @@ -13,6 +13,9 @@ class DummyDataSource(BaseDataSource): def run(self, *args, **kwargs): pass + def slots(self, model): + return (), () + class TestBaseDataSource(unittest.TestCase): def test_initialization(self): diff --git a/force_bdss/kpi/base_kpi_calculator.py b/force_bdss/kpi/base_kpi_calculator.py index 1bb1bf4867755639e5edf999ef9748a0e0cd8495..b757dd403a9460d53e04d3aa7dd13ac833c5d2a2 100644 --- a/force_bdss/kpi/base_kpi_calculator.py +++ b/force_bdss/kpi/base_kpi_calculator.py @@ -38,3 +38,32 @@ class BaseKPICalculator(ABCHasStrictTraits): List[DataValue]: The result of this KPI evaluation, as a list of DataValues. """ + + @abc.abstractmethod + def slots(self, model): + """Returns the input (and output) slots of the KPI Calculator. + Slots are the entities that are needed (and produced) by this + KPI Calculator. + + The slots may depend on the configuration options, and thus the model. + This allows, for example, to change the slots depending if an option + is enabled or not. + + Parameters + ---------- + model: BaseKPICalculatorModel + The model of the KPICalculator, instantiated through create_model() + + Returns + ------- + (input_slots, output_slots): tuple[tuple, tuple] + A tuple containing two tuples. + The first element is the input slots, the second element is + the output slots. Each slot must be an instance of the Slot class. + It is possible for each of the two inside tuples to be empty. + The case of an empty input slot is common: the KPICalculator does + not need any information from the MCO to operate. + The case of an empty output slot is uncommon, but supported: + the KPICalculator does not produce any output and is therefore + useless. + """ diff --git a/force_bdss/kpi/tests/test_base_kpi_calculator.py b/force_bdss/kpi/tests/test_base_kpi_calculator.py index 548383573691a320db5ec29c4664a62037a9be53..334c1915535d576c9d444a4de0e60fef6f13706a 100644 --- a/force_bdss/kpi/tests/test_base_kpi_calculator.py +++ b/force_bdss/kpi/tests/test_base_kpi_calculator.py @@ -12,6 +12,9 @@ class DummyKPICalculator(BaseKPICalculator): def run(self, *args, **kwargs): pass + def slots(self, model): + return (), () + class TestBaseKPICalculator(unittest.TestCase): def test_initialization(self): diff --git a/force_bdss/tests/test_core_evaluation_driver.py b/force_bdss/tests/test_core_evaluation_driver.py index 3ce84809480eb25565fb014814feed26888313e8..fc79b484871b7e065956eccfe2a532a008c6db48 100644 --- a/force_bdss/tests/test_core_evaluation_driver.py +++ b/force_bdss/tests/test_core_evaluation_driver.py @@ -80,6 +80,9 @@ class NullKPICalculator(BaseKPICalculator): def run(self, model, data_source_results): return [] + def slots(self, model): + return (), () + class NullKPICalculatorBundle(BaseKPICalculatorBundle): def create_model(self, model_data=None): @@ -97,6 +100,9 @@ class NullDataSource(BaseDataSource): def run(self, model, parameters): return [] + def slots(self, model): + return (), () + class NullDataSourceBundle(BaseDataSourceBundle): def create_model(self, model_data=None):