diff --git a/k4FWCore/components/EventCounter.cpp b/k4FWCore/components/EventCounter.cpp new file mode 100644 index 00000000..f1bd0310 --- /dev/null +++ b/k4FWCore/components/EventCounter.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Gaudi/Accumulators.h" +#include "Gaudi/Functional/Consumer.h" + +class EventCounter final : public Gaudi::Functional::Consumer { +public: + using Consumer::Consumer; + + void operator()(const EventContext& ctx) const override { + ++m_count; + if (m_frequency && (ctx.evt() % m_frequency == 0)) { + info() << "Processing event " << ctx.evt() << endmsg; + } + } + + StatusCode finalize() override { + info() << "Processed " << m_count.value() << " events" << endmsg; + return Consumer::finalize(); + } + +private: + mutable Gaudi::Accumulators::Counter<> m_count{this, "count"}; + Gaudi::Property m_frequency{this, "Frequency", 1, "How often to print the event number"}; +}; + +DECLARE_COMPONENT(EventCounter) diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 6d48d076..e8457b2f 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -139,6 +139,9 @@ add_test_with_env(Testk4runCustomArguments options/TestArgs.py --foo=42 PROPERTI add_test_with_env(Testk4runVerboseOutput options/TestArgs.py --verbose PROPERTIES PASS_REGULAR_EXPRESSION " VERBOSE ") add_test_with_env(Testk4runHelpOnly options/TestArgs.py --help PROPERTIES PASS_REGULAR_EXPRESSION "show this help message and exit") +add_test_with_env(TestEventCounter options/TestEventCounter.py) +set_tests_properties(TestEventCounter PROPERTIES FAIL_REGULAR_EXPRESSION "Processing event 1;Processing event 3" + PASS_REGULAR_EXPRESSION "(Processing event 0.*Processing event 2|Processing event 2.*Processing event 0).*Processed 4 events.*Processed 4 events") add_test_with_env(FunctionalMemory options/ExampleFunctionalMemory.py) add_test_with_env(FunctionalMTMemory options/ExampleFunctionalMTMemory.py) diff --git a/test/k4FWCoreTest/options/TestEventCounter.py b/test/k4FWCoreTest/options/TestEventCounter.py new file mode 100644 index 00000000..e23b7b0b --- /dev/null +++ b/test/k4FWCoreTest/options/TestEventCounter.py @@ -0,0 +1,60 @@ +# +# Copyright (c) 2014-2024 Key4hep-Project. +# +# This file is part of Key4hep. +# See https://key4hep.github.io/key4hep-doc/ for further info. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This is an example of counting events with EventCounter algorithm. +# During execution the EventCounter algorithms will printout current event number depending on the frequency. +# The summary about total number of events passed through that algorithms is handled by MessageSvcSink + +from Gaudi.Configuration import INFO, WARNING +from Configurables import EventCounter +from Configurables import HiveSlimEventLoopMgr, HiveWhiteBoard, AvalancheSchedulerSvc +from k4FWCore import ApplicationMgr + +evtslots = 4 +threads = 4 + +whiteboard = HiveWhiteBoard( + "EventDataSvc", + EventSlots=evtslots, + ForceLeaves=True, +) + +slimeventloopmgr = HiveSlimEventLoopMgr( + "HiveSlimEventLoopMgr", + SchedulerName="AvalancheSchedulerSvc", + Warnings=False, + OutputLevel=WARNING, +) + +scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, ShowDataFlow=True, OutputLevel=WARNING) + +counter_1 = EventCounter("SilentEventCounter", Frequency=0, OutputLevel=INFO) +counter_2 = EventCounter("EventCounter", Frequency=2, OutputLevel=INFO) + + +mgr = ApplicationMgr( + TopAlg=[counter_1, counter_2], + EvtSel="NONE", + EvtMax=4, + # Add "MessageSvcSink" for a table at the end with a statistical summary of the counter data + # ExtSvc=[whiteboard, "Gaudi::Monitoring::MessageSvcSink"], + ExtSvc=[whiteboard], + EventLoop=slimeventloopmgr, + OutputLevel=INFO, +)