diff --git a/k4FWCore/components/PodioInput.cpp b/k4FWCore/components/PodioInput.cpp index 12ce8a88..2356ee46 100644 --- a/k4FWCore/components/PodioInput.cpp +++ b/k4FWCore/components/PodioInput.cpp @@ -184,14 +184,15 @@ PodioInput::PodioInput(const std::string& name, ISvcLocator* svcLoc) : Consumer( error() << "Could not get PodioDataSvc" << endmsg; } fillReaders(); - - auto key = edm4hep::EventHeaderName; - if (std::find(m_collectionNames.begin(), m_collectionNames.end(), key) == m_collectionNames.end()) { - m_collectionNames.value().push_back(key); - } } void PodioInput::operator()() const { + if (m_podioDataSvc->getEventFrame().get(edm4hep::EventHeaderName)) { + m_readers[edm4hep::EventHeaderCollection::typeName](edm4hep::EventHeaderName); + } else { + info() << "No EventHeader collection found in the event. Not reading it" << endmsg; + } + for (auto& collName : m_collectionNames) { debug() << "Registering collection to read " << collName << endmsg; auto type = m_podioDataSvc->getCollectionType(collName); diff --git a/k4FWCore/include/k4FWCore/PodioDataSvc.h b/k4FWCore/include/k4FWCore/PodioDataSvc.h index 5343a034..f349be43 100644 --- a/k4FWCore/include/k4FWCore/PodioDataSvc.h +++ b/k4FWCore/include/k4FWCore/PodioDataSvc.h @@ -69,6 +69,11 @@ class PodioDataSvc : public DataSvc { const std::string_view getCollectionType(const std::string& collName); template StatusCode readCollection(const std::string& collName) { + DataObject* objectPtr = nullptr; + if (DataSvc::findObject("/Event", "/" + collName, objectPtr)) { + debug() << "Collection " << collName << " already read, not reading it again" << endmsg; + return StatusCode::SUCCESS; + } const T* collection(nullptr); collection = static_cast(m_eventframe.get(collName)); if (collection == nullptr) { diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 49ad4607..19f40204 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -95,6 +95,7 @@ add_test_with_env(TestDataHandleUniquePtr options/TestDataHandleUniquePtr.py) add_test_with_env(TestUniqueIDGenSvc options/TestUniqueIDGenSvc.py) add_test_with_env(CreateLegacyExampleEventData options/createLegacyExampleEventData.py) add_test_with_env(TestEventHeaderFiller options/createEventHeader.py) +add_test_with_env(EventHeaderCheck options/runEventHeaderCheck.py PROPERTIES DEPENDS TestEventHeaderFiller) add_test(NAME TestExec WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND python options/TestExec.py) set_test_env(TestExec) diff --git a/test/k4FWCoreTest/options/runEventHeaderCheck.py b/test/k4FWCoreTest/options/runEventHeaderCheck.py new file mode 100644 index 00000000..64f673c7 --- /dev/null +++ b/test/k4FWCoreTest/options/runEventHeaderCheck.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2014-2023 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. +# + +from Gaudi.Configuration import INFO +from Configurables import k4DataSvc +from Configurables import PodioInput +from Configurables import ExampleEventHeaderConsumer +from Configurables import ApplicationMgr + +podioevent = k4DataSvc("EventDataSvc") +podioevent.input = "eventHeader.root" + +inp = PodioInput() +inp.collections = [] + +consumer = ExampleEventHeaderConsumer( + "EventHeaderCheck", runNumber=42, eventNumberOffset=42 +) + +ApplicationMgr( + TopAlg=[inp, consumer], + EvtSel="NONE", + EvtMax=-1, + ExtSvc=[podioevent], + OutputLevel=INFO, +) diff --git a/test/k4FWCoreTest/src/components/ExampleEventHeaderConsumer.cpp b/test/k4FWCoreTest/src/components/ExampleEventHeaderConsumer.cpp new file mode 100644 index 00000000..487f10c1 --- /dev/null +++ b/test/k4FWCoreTest/src/components/ExampleEventHeaderConsumer.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014-2023 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 "edm4hep/Constants.h" +#include "edm4hep/EventHeaderCollection.h" + +#include "k4FWCore/BaseClass.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + +struct ExampleEventHeaderConsumer final + : Gaudi::Functional::Consumer { + ExampleEventHeaderConsumer(const std::string& name, ISvcLocator* svcLoc) + : Consumer(name, svcLoc, {KeyValue("EventHeaderName", edm4hep::EventHeaderName)}) {} + + void operator()(const edm4hep::EventHeaderCollection& evtHeaderColl) const { + if (evtHeaderColl.empty()) { + throw std::runtime_error("EventHeader collection is empty"); + } + const auto evtHeader = evtHeaderColl[0]; + if (!evtHeader.isAvailable()) { + throw std::runtime_error("Cannot get a valid EventHeader"); + } + + if (evtHeader.getRunNumber() != m_runNumber) { + throw std::runtime_error(fmt::format("Run number is not set correctly (expected {}, actual {})", + m_runNumber.value(), evtHeader.getRunNumber())); + } + + const auto expectedEvent = m_evtCounter++ + m_eventNumberOffset; + if (evtHeader.getEventNumber() != expectedEvent) { + throw std::runtime_error(fmt::format("Event number is not set correctly (expected {}, actual {})", expectedEvent, + evtHeader.getEventNumber())); + } + } + + Gaudi::Property m_runNumber{this, "runNumber", 0, "The expected run number"}; + Gaudi::Property m_eventNumberOffset{this, "eventNumberOffset", 0, + "The event number offset where events will start counting from"}; + mutable std::atomic m_evtCounter{0}; +}; + +DECLARE_COMPONENT(ExampleEventHeaderConsumer)