From 90eec176526d75b29e69ae12750a89fca092d2d5 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Mon, 20 Apr 2026 09:52:06 +0200 Subject: [PATCH 1/3] Disallow setting metadata parameters in the event loop --- k4FWCore/components/MetadataSvc.cpp | 8 ++++++++ k4FWCore/components/MetadataSvc.h | 1 + k4FWCore/include/k4FWCore/IMetadataSvc.h | 3 +++ 3 files changed, 12 insertions(+) diff --git a/k4FWCore/components/MetadataSvc.cpp b/k4FWCore/components/MetadataSvc.cpp index fb9d7d76a..1b32f5490 100644 --- a/k4FWCore/components/MetadataSvc.cpp +++ b/k4FWCore/components/MetadataSvc.cpp @@ -22,8 +22,10 @@ #include "podio/Frame.h" #include +#include #include #include +#include #include @@ -43,6 +45,12 @@ StatusCode MetadataSvc::initialize() { StatusCode MetadataSvc::finalize() { return Service::finalize(); } +void MetadataSvc::throwIfRunning() const { + if (targetFSMState() == Gaudi::StateMachine::RUNNING) { + throw GaudiException("putParameter cannot be called during the event loop", name(), StatusCode::FAILURE); + } +} + const podio::Frame* MetadataSvc::getFrame() const { return m_frame.get(); } podio::Frame* MetadataSvc::getFrame() { return m_frame.get(); } void MetadataSvc::setFrame(podio::Frame frame) { m_frame = std::make_unique(std::move(frame)); } diff --git a/k4FWCore/components/MetadataSvc.h b/k4FWCore/components/MetadataSvc.h index eb482dd95..ed2ea2012 100644 --- a/k4FWCore/components/MetadataSvc.h +++ b/k4FWCore/components/MetadataSvc.h @@ -43,6 +43,7 @@ class MetadataSvc : public extends { const podio::Frame* getFrame() const override; podio::Frame* getFrame() override; void setFrame(podio::Frame frame) override; + void throwIfRunning() const override; }; #endif diff --git a/k4FWCore/include/k4FWCore/IMetadataSvc.h b/k4FWCore/include/k4FWCore/IMetadataSvc.h index c0365e84c..f9c2ad7ef 100644 --- a/k4FWCore/include/k4FWCore/IMetadataSvc.h +++ b/k4FWCore/include/k4FWCore/IMetadataSvc.h @@ -35,6 +35,7 @@ class IMetadataSvc : virtual public IInterface { template void put(const std::string& name, const T& obj) { + throwIfRunning(); getFrameForWrite()->putParameter(name, obj); } @@ -50,6 +51,7 @@ class IMetadataSvc : virtual public IInterface { protected: virtual podio::Frame* getFrame() = 0; virtual const podio::Frame* getFrame() const = 0; + virtual void throwIfRunning() const {} private: podio::Frame* getFrameForWrite() { @@ -63,6 +65,7 @@ class IMetadataSvc : virtual public IInterface { template <> inline void IMetadataSvc::put(const std::string& collName, const edm4hep::utils::ParticleIDMeta& pidMetaInfo) { + throwIfRunning(); edm4hep::utils::PIDHandler::setAlgoInfo(*getFrameForWrite(), collName, pidMetaInfo); } From 41f03d7aeda19ae8be9921bce886bfb07a1a126f Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Mon, 20 Apr 2026 09:52:20 +0200 Subject: [PATCH 2/3] Add test --- test/k4FWCoreTest/CMakeLists.txt | 2 + .../ExampleFunctionalMetadataEventLoop.py | 39 +++++++++++++++++++ .../ExampleFunctionalMetadataProducer.cpp | 7 +++- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index fd9569455..f8f79ab87 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -218,6 +218,8 @@ add_test_fwcore(FunctionalCollectionMerger options/ExampleFunctionalCollectionMe add_test_fwcore(FunctionalFilterFile options/ExampleFunctionalFilterFile.py ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMetadata options/ExampleFunctionalMetadata.py ADD_TO_CHECK_FILES PROPERTIES FIXTURES_SETUP FunctionalMetadataFile) add_test_fwcore(FunctionalMetadataRead options/ExampleFunctionalMetadataRead.py PROPERTIES FIXTURES_REQUIRED FunctionalMetadataFile ADD_TO_CHECK_FILES) +add_test_fwcore(FunctionalMetadataEventLoop options/ExampleFunctionalMetadataEventLoop.py + PROPERTIES PASS_REGULAR_EXPRESSION "putParameter cannot be called during the event loop") add_test_fwcore(FunctionalMetadataOldAlgorithm options/ExampleFunctionalMetadataOldAlgorithm.py ADD_TO_CHECK_FILES PROPERTIES FIXTURES_SETUP OldAlgorithmFile) add_test_fwcore(createEventHeaderConcurrent options/createEventHeaderConcurrent.py ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMetadataReadOldAlgorithm options/ExampleFunctionalMetadataReadOldAlgorithm.py PROPERTIES FIXTURES_REQUIRED OldAlgorithmFile ADD_TO_CHECK_FILES) diff --git a/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py b/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py new file mode 100644 index 000000000..297abc51c --- /dev/null +++ b/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py @@ -0,0 +1,39 @@ +# +# 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 test verifies that calling putParameter during the event loop raises an error + +from Gaudi.Configuration import INFO +from Configurables import ExampleFunctionalMetadataProducer +from k4FWCore import ApplicationMgr +from Configurables import EventDataSvc, MetadataSvc + +producer = ExampleFunctionalMetadataProducer( + "Producer", + OutputCollection=["MCParticles"], + PutMetadataInEventLoop=True, +) + +ApplicationMgr( + TopAlg=[producer], + EvtSel="NONE", + EvtMax=3, + ExtSvc=[EventDataSvc("EventDataSvc"), MetadataSvc("MetadataSvc")], + OutputLevel=INFO, +) diff --git a/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp b/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp index 2e568d99d..ee6e60194 100644 --- a/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp +++ b/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp @@ -42,8 +42,9 @@ struct ExampleFunctionalMetadataProducer final : k4FWCore::Producer m_putMetadataInEventLoop{this, "PutMetadataInEventLoop", false, + "If true, attempt to put metadata during the event loop (will throw)"}; Gaudi::Property m_intProp{this, "intProp", 42, "An integer property"}; Gaudi::Property m_intProp2{this, "intProp2", 42, "An integer property"}; Gaudi::Property m_floatProp{this, "floatProp", 3.14, "A float property"}; From 2f484ca5c466db60268900ebee3e68503e3be2d0 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Mon, 20 Apr 2026 11:12:24 +0200 Subject: [PATCH 3/3] Move `throwIfRunning` inside `getFrameForWrite` --- k4FWCore/include/k4FWCore/IMetadataSvc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/k4FWCore/include/k4FWCore/IMetadataSvc.h b/k4FWCore/include/k4FWCore/IMetadataSvc.h index f9c2ad7ef..9ec3ecd10 100644 --- a/k4FWCore/include/k4FWCore/IMetadataSvc.h +++ b/k4FWCore/include/k4FWCore/IMetadataSvc.h @@ -35,7 +35,6 @@ class IMetadataSvc : virtual public IInterface { template void put(const std::string& name, const T& obj) { - throwIfRunning(); getFrameForWrite()->putParameter(name, obj); } @@ -55,6 +54,7 @@ class IMetadataSvc : virtual public IInterface { private: podio::Frame* getFrameForWrite() { + throwIfRunning(); if (!getFrame()) { setFrame(podio::Frame()); } @@ -65,7 +65,6 @@ class IMetadataSvc : virtual public IInterface { template <> inline void IMetadataSvc::put(const std::string& collName, const edm4hep::utils::ParticleIDMeta& pidMetaInfo) { - throwIfRunning(); edm4hep::utils::PIDHandler::setAlgoInfo(*getFrameForWrite(), collName, pidMetaInfo); }