From a0f4dc2fd4e6a9400d1dbc86a64a50c507348f2c Mon Sep 17 00:00:00 2001 From: Christopher Dilks Date: Tue, 14 Nov 2023 11:47:46 -0500 Subject: [PATCH] feat: check algorithm input banks --- .../EventBuilderFilter.cc | 3 ++ src/services/Algorithm.cc | 21 ++++++++++++-- src/services/Algorithm.h | 28 ++++++++++++++++++- src/tests/main.cc | 4 +-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/algorithms/clas12/event_builder_filter/EventBuilderFilter.cc b/src/algorithms/clas12/event_builder_filter/EventBuilderFilter.cc index 6bc2ff6f..3d59c017 100644 --- a/src/algorithms/clas12/event_builder_filter/EventBuilderFilter.cc +++ b/src/algorithms/clas12/event_builder_filter/EventBuilderFilter.cc @@ -7,6 +7,9 @@ namespace iguana::clas12 { } Algorithm::BankMap EventBuilderFilter::Run(Algorithm::BankMap inputBanks) { + + if(MissingInputBanks(inputBanks, {"particles"})) ThrowRun(); + return inputBanks; } diff --git a/src/services/Algorithm.cc b/src/services/Algorithm.cc index d6d69f5c..8608432e 100644 --- a/src/services/Algorithm.cc +++ b/src/services/Algorithm.cc @@ -2,8 +2,25 @@ namespace iguana { - Algorithm::Algorithm(std::string name) { - m_log = std::make_shared(name); + Algorithm::Algorithm(std::string name) : m_name(name) { + m_log = std::make_shared(m_name); + } + + bool Algorithm::MissingInputBanks(BankMap banks, std::set keys) { + for(auto key : keys) { + if(banks.find(key) == banks.end()) { + m_log->Error("Algorithm '{}' is missing the input bank '{}'", m_name, key); + m_log->Error(" => the following input banks are required by '{}':", m_name); + for(auto k : keys) + m_log->Error(" - {}", k); + return true; + } + } + return false; + } + + void Algorithm::ThrowRun() { + throw std::runtime_error(fmt::format("Algorithm '{}' cannot `Run`", m_name)); } } diff --git a/src/services/Algorithm.h b/src/services/Algorithm.h index 624a9c2b..f82ddac0 100644 --- a/src/services/Algorithm.h +++ b/src/services/Algorithm.h @@ -2,6 +2,7 @@ #include "Logger.h" #include +#include namespace iguana { @@ -11,14 +12,39 @@ namespace iguana { using BankMap = std::unordered_map; + /// Algorithm base class constructor + /// @param name the unique name for a derived class instance Algorithm(std::string name); + /// Algorithm base class destructor + virtual ~Algorithm() {} + + /// Initialize an algorithm before any events are processed virtual void Start() = 0; + + /// Run an algorithm + /// @param inputBanks the set of input banks + /// @return a set of output banks virtual BankMap Run(BankMap inputBanks) = 0; + + /// Finalize an algorithm after all events are processed virtual void Stop() = 0; - virtual ~Algorithm() {} protected: + + /// Check if `banks` contains all keys `keys`; this is useful for checking algorithm inputs are complete. + /// @param banks the set of (key,bank) pairs to check + /// @keys the required keys + /// @return true if `banks` is missing any keys in `keys` + bool MissingInputBanks(BankMap banks, std::set keys); + + /// Throw a runtime exception when calling `Run` + void ThrowRun(); + + /// algorithm name + std::string m_name; + + /// Logger std::shared_ptr m_log; }; } diff --git a/src/tests/main.cc b/src/tests/main.cc index a372214d..65bfbfe8 100644 --- a/src/tests/main.cc +++ b/src/tests/main.cc @@ -25,9 +25,9 @@ int main(int argc, char **argv) { reader.read(event); event.getStructure(particleBank); - auto resultBank = algo->Run({{"REC::Particle", particleBank}}); + auto resultBank = algo->Run({{"particles", particleBank}}); - fmt::print("BEFORE -> AFTER: {} -> {}\n", particleBank.getRows(), resultBank.at("REC::Particle").getRows()); + fmt::print("BEFORE -> AFTER: {} -> {}\n", particleBank.getRows(), resultBank.at("particles").getRows()); count++; }