From fd6f53a47935bcac7ab72cefea995a7b108db4b3 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 20:45:21 +0200 Subject: [PATCH 01/16] Add utiltity functions for storing collection parameters --- k4FWCore/include/k4FWCore/MetadataUtils.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/k4FWCore/include/k4FWCore/MetadataUtils.h b/k4FWCore/include/k4FWCore/MetadataUtils.h index ca8cd8eb..2b527108 100644 --- a/k4FWCore/include/k4FWCore/MetadataUtils.h +++ b/k4FWCore/include/k4FWCore/MetadataUtils.h @@ -194,6 +194,27 @@ std::optional getCellIDEncoding(const std::string& collName, const return getCollectionParameter(collName, edm4hep::labels::CellIDEncoding, comp); } +/// @brief Get a metadata parameter associated with a collection from the metadata +/// +/// Internally builds the correct parameter name from the collection name and +/// parameter name and then retrieves the value from the metadata frame via the +/// MetadataSvc +/// +/// @param collName The name of the collection for which the parameter should be +/// retrieved +/// @param paramName The name of the parameter +/// @param comp The Gaudi component (algorithm, tool) that is retrieving the +/// parameter, typically "this" +/// @tparam T The type of the parameter value +/// @tparam GaudiComp The type of the component. This will be deduced in +/// pretty much all of the use cases +/// @return The parameter value if it has been found or std::nullopt if not +template +std::optional getCollectionParameter(const std::string& collName, const std::string& paramName, + const GaudiComp* comp) { + return getParameter(podio::collMetadataParamName(collName, paramName), comp); +} + } // namespace k4FWCore #endif // FWCORE_METADATAUTILS_H From 102ded13ec0e8f94ff12c29e31fa8c44298bb67e Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 15:06:43 +0200 Subject: [PATCH 02/16] Remove deprectated components related to legacy Podio I/O Remove all components that have been marked as deprecated and make things compile again --- k4FWCore/CMakeLists.txt | 9 +- k4FWCore/components/FCCDataSvc.cpp | 30 --- k4FWCore/components/FCCDataSvc.h | 31 --- k4FWCore/components/PodioInput.cpp | 213 --------------------- k4FWCore/components/PodioInput.h | 61 ------ k4FWCore/components/PodioOutput.cpp | 150 --------------- k4FWCore/components/PodioOutput.h | 65 ------- k4FWCore/components/k4DataSvc.cpp | 31 --- k4FWCore/components/k4DataSvc.h | 30 --- k4FWCore/include/k4FWCore/MetaDataHandle.h | 175 ----------------- k4FWCore/include/k4FWCore/PodioDataSvc.h | 131 ------------- k4FWCore/src/PodioDataSvc.cpp | 192 ------------------- 12 files changed, 2 insertions(+), 1116 deletions(-) delete mode 100644 k4FWCore/components/FCCDataSvc.cpp delete mode 100644 k4FWCore/components/FCCDataSvc.h delete mode 100644 k4FWCore/components/PodioInput.cpp delete mode 100644 k4FWCore/components/PodioInput.h delete mode 100644 k4FWCore/components/PodioOutput.cpp delete mode 100644 k4FWCore/components/PodioOutput.h delete mode 100644 k4FWCore/components/k4DataSvc.cpp delete mode 100644 k4FWCore/components/k4DataSvc.h delete mode 100644 k4FWCore/include/k4FWCore/MetaDataHandle.h delete mode 100644 k4FWCore/include/k4FWCore/PodioDataSvc.h delete mode 100644 k4FWCore/src/PodioDataSvc.cpp diff --git a/k4FWCore/CMakeLists.txt b/k4FWCore/CMakeLists.txt index 203ab57e..d19c08e5 100644 --- a/k4FWCore/CMakeLists.txt +++ b/k4FWCore/CMakeLists.txt @@ -20,8 +20,7 @@ limitations under the License. gaudi_install(SCRIPTS) gaudi_add_library(k4FWCore - SOURCES src/PodioDataSvc.cpp - src/KeepDropSwitch.cpp + SOURCES src/KeepDropSwitch.cpp LINK Gaudi::GaudiKernel podio::podioIO ROOT::Core ROOT::RIO ROOT::Tree EDM4HEP::utils ) target_include_directories(k4FWCore PUBLIC @@ -34,17 +33,13 @@ gaudi_add_module(k4FWCorePlugins components/EfficiencyFilter.cpp components/EventCounter.cpp components/EventHeaderCreator.cpp - components/FCCDataSvc.cpp components/IOSvc.cpp components/MetadataSvc.cpp components/OverlayTiming.cpp - components/PodioInput.cpp - components/PodioOutput.cpp components/Reader.cpp components/UniqueIDGenSvc.cpp components/Writer.cpp - components/k4DataSvc.cpp - LINK Gaudi::GaudiKernel k4FWCore k4FWCore::k4Interface ROOT::Core ROOT::RIO ROOT::Tree ROOT::MathCore EDM4HEP::edm4hep podio::podioIO) + LINK Gaudi::GaudiKernel k4FWCore k4FWCore::k4Interface ROOT::Core ROOT::RIO ROOT::Tree EDM4HEP::edm4hep) target_include_directories(k4FWCorePlugins PUBLIC $ diff --git a/k4FWCore/components/FCCDataSvc.cpp b/k4FWCore/components/FCCDataSvc.cpp deleted file mode 100644 index 088bd07e..00000000 --- a/k4FWCore/components/FCCDataSvc.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 "FCCDataSvc.h" - -// Instantiation of a static factory class used by clients to create -// instances of this service -DECLARE_COMPONENT(FCCDataSvc) - -/// Standard Constructor -FCCDataSvc::FCCDataSvc(const std::string& name, ISvcLocator* svc) : PodioDataSvc(name, svc) { - declareProperty("inputs", m_filenames = {}, "Names of the files to read"); - declareProperty("input", m_filename = "", "Name of the file to read"); -} diff --git a/k4FWCore/components/FCCDataSvc.h b/k4FWCore/components/FCCDataSvc.h deleted file mode 100644 index e900a114..00000000 --- a/k4FWCore/components/FCCDataSvc.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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. - */ - -#ifndef K4FWCORE_FCCDATASVC_H -#define K4FWCORE_FCCDATASVC_H - -#include "k4FWCore/PodioDataSvc.h" - -/// an alias to k4DataSvc for backwards compatibility -class [[deprecated("Use the IOSvc instead")]] FCCDataSvc : public PodioDataSvc { -public: - /// Standard Constructor - FCCDataSvc(const std::string& name, ISvcLocator* svc); -}; -#endif diff --git a/k4FWCore/components/PodioInput.cpp b/k4FWCore/components/PodioInput.cpp deleted file mode 100644 index 74d208b4..00000000 --- a/k4FWCore/components/PodioInput.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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 "PodioInput.h" -#include "Gaudi/Functional/Consumer.h" - -#include "k4FWCore/PodioDataSvc.h" - -#include "edm4hep/edm4hep.h" - -#include "podio/UserDataCollection.h" - -DECLARE_COMPONENT(PodioInput) - -template -inline void PodioInput::maybeRead(std::string_view collName) const { - if (m_podioDataSvc->readCollection(std::string(collName)).isFailure()) { - error() << "Failed to register collection " << collName << endmsg; - } -} - -void PodioInput::fillReaders() { - m_readers["edm4hep::MCParticleCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::SimTrackerHitCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::CaloHitContributionCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::SimCalorimeterHitCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::RawCalorimeterHitCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::CalorimeterHitCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::ParticleIDCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::ClusterCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackerHit3DCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackerHitCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackerHitPlaneCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::RawTimeSeriesCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::VertexCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::ReconstructedParticleCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::RecoMCParticleLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::CaloHitSimCaloHitLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackerHitSimTrackerHitLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::CaloHitMCParticleLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::ClusterMCParticleLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TrackMCParticleLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::VertexRecoParticleLinkCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::TimeSeriesCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["edm4hep::RecDqdxCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["podio::UserDataCollection"] = [&](std::string_view collName) { - maybeRead>(collName); - }; - m_readers["edm4hep::EventHeaderCollection"] = [&](std::string_view collName) { - maybeRead(collName); - }; -} - -PodioInput::PodioInput(const std::string& name, ISvcLocator* svcLoc) : Consumer(name, svcLoc) { - // do not do anything during the genconf step - const std::string cmd = System::cmdLineArgs()[0]; - if (cmd.find("genconf") != std::string::npos) - return; - - // check whether we have the PodioEvtSvc active - m_podioDataSvc = dynamic_cast(evtSvc().get()); - if (!m_podioDataSvc) { - error() << "Could not get PodioDataSvc" << endmsg; - } - fillReaders(); -} - -StatusCode PodioInput::initialize() { - warning() << "PodioInput is deprecated and will be removed. Use the IOSvc instead" << endmsg; - // If someone uses the collections property from the command line and passes - // an empty string we assume they want all collections (as a simple way to - // override whatever is in the options file) - if (m_collectionNames.size() == 1 && m_collectionNames[0].empty()) { - m_collectionNames.clear(); - } - - debug() << "Setting collections to read to: " << m_collectionNames.value() << endmsg; - m_podioDataSvc->setCollsToRead(m_collectionNames); - - return StatusCode::SUCCESS; -} - -StatusCode PodioInput::finalize() { - warning() << "PodioInput is deprecated and will be removed. Use the IOSvc instead" << endmsg; - return StatusCode::SUCCESS; -} - -void PodioInput::operator()() const { - if (m_podioDataSvc->getEventFrame().get(edm4hep::labels::EventHeader)) { - m_readers[edm4hep::EventHeaderCollection::typeName](edm4hep::labels::EventHeader); - } else { - info() << "No EventHeader collection found in the event. Not reading it" << endmsg; - } - - const auto& collsToRead = [&]() { - if (m_collectionNames.empty()) { - return m_podioDataSvc->getEventFrame().getAvailableCollections(); - } else { - return m_collectionNames.value(); - } - }(); - - for (const auto& collName : collsToRead) { - debug() << "Registering collection to read " << collName << endmsg; - if (!m_podioDataSvc->getEventFrame().get(collName)) { - warning() << "Collection " << collName << " is not available from file." << endmsg; - continue; - } - auto type = m_podioDataSvc->getCollectionType(collName); - if (m_readers.find(type) != m_readers.end()) { - m_readers[type](collName); - } else { - maybeRead(collName); - } - } - - // Tell data service that we are done with requested collections - m_podioDataSvc->endOfRead(); -} diff --git a/k4FWCore/components/PodioInput.h b/k4FWCore/components/PodioInput.h deleted file mode 100644 index 81c88d3b..00000000 --- a/k4FWCore/components/PodioInput.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ -#ifndef FWCORE_PODIOINPUT_H -#define FWCORE_PODIOINPUT_H -// Gaudi -#include "Gaudi/Functional/Consumer.h" -#include "Gaudi/Property.h" - -// STL -#include -#include - -class PodioDataSvc; - -/** @class PodioInput - * - * Class that allows to read ROOT files written with PodioOutput - * - * @author J. Lingemann - */ - -using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t; - -class [[deprecated("Use the IOSvc instead")]] PodioInput final - : public Gaudi::Functional::Consumer { -public: - PodioInput(const std::string& name, ISvcLocator* svcLoc); - void operator()() const override; - - StatusCode initialize() final; - StatusCode finalize() final; - -private: - template - void maybeRead(std::string_view collName) const; - void fillReaders(); - // Name of collections to read. Set by option collections (this is temporary) - Gaudi::Property> m_collectionNames{ - this, "collections", {}, "Collections that should be read (default all)"}; - // Data service: needed to register objects and get collection IDs. Just an observing pointer. - PodioDataSvc* m_podioDataSvc; - mutable std::map> m_readers; -}; - -#endif diff --git a/k4FWCore/components/PodioOutput.cpp b/k4FWCore/components/PodioOutput.cpp deleted file mode 100644 index fcc3e200..00000000 --- a/k4FWCore/components/PodioOutput.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 -#include -#include - -#include "GaudiKernel/MsgStream.h" - -#include "PodioOutput.h" -#include "k4FWCore/PodioDataSvc.h" - -DECLARE_COMPONENT(PodioOutput) - -PodioOutput::PodioOutput(const std::string& name, ISvcLocator* svcLoc) - : Gaudi::Algorithm(name, svcLoc), m_firstEvent(true) {} - -StatusCode PodioOutput::initialize() { - warning() << "PodioOutput is deprecated and will be removed. Use the IOSvc instead" << endmsg; - if (Gaudi::Algorithm::initialize().isFailure()) - return StatusCode::FAILURE; - - // check whether we have the PodioEvtSvc active - m_podioDataSvc = dynamic_cast(evtSvc().get()); - if (nullptr == m_podioDataSvc) { - error() << "Could not get DataSvc!" << endmsg; - return StatusCode::FAILURE; - } - - // check whether output directory needs to be created and eventually create it - auto outDirPath = std::filesystem::path(m_filename.value()).parent_path(); - if (!outDirPath.empty() && !std::filesystem::is_directory(outDirPath)) { - std::error_code ec; - std::filesystem::create_directories(outDirPath, ec); - if (ec.value() != 0) { - error() << "Output directory \"" << outDirPath << "\" was not created!" << endmsg; - error() << "Error " << ec.value() << ": " << ec.message() << endmsg; - - return StatusCode::FAILURE; - } - debug() << "Created output directory: " << outDirPath << endmsg; - } - - m_framewriter = std::make_unique(m_filename); - try { - m_switch = k4FWCore::KeepDropSwitch(m_outputCommands); - } catch (const std::invalid_argument& ex) { - fatal() << ex.what() << endmsg; - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; -} - -StatusCode PodioOutput::execute(const EventContext&) const { - auto& frame = m_podioDataSvc->getEventFrame(); - - // register for writing - if (m_firstEvent) { - auto collections = frame.getAvailableCollections(); - for (auto& collection_name : collections) { - if (m_switch.isOn(collection_name)) { - m_collection_names_to_write.push_back(collection_name); - } - } - m_framewriter->writeFrame(frame, "events", m_collection_names_to_write); - } else { - try { - m_framewriter->writeFrame(frame, "events", m_collection_names_to_write); - } catch (std::runtime_error&) { - // In this error message we are only interested in the ones that are - // missing, since only a missing collection can trigger the exception - // here. Additional collections that are present in the Frame are not - // necessarily an issue here, because we might just be configured to not - // write all of them - const auto& [missing, _] = m_framewriter->checkConsistency(frame.getAvailableCollections(), "events"); - error() << "Could not write event, because the following collections are not present: "; - std::string sep = ""; - for (const auto& name : missing) { - error() << sep << name; - sep = ", "; - } - error() << endmsg; - - return StatusCode::FAILURE; - } - } - m_firstEvent = false; - - return StatusCode::SUCCESS; -} - -/** PodioOutput::finalize - * has to happen after all algorithms that touch the data store finish. - * Here the job options are retrieved and stored to disk as a branch - * in the metadata tree. - * - */ -StatusCode PodioOutput::finalize() { - warning() << "PodioOutput is deprecated and will be removed. Use the IOSvc instead" << endmsg; - - if (Gaudi::Algorithm::finalize().isFailure()) - return StatusCode::FAILURE; - //// prepare job options metadata /////////////////////// - // retrieve the configuration of the job - // and write it to file as vector of strings - std::vector config_data; - const auto& jobOptionsSvc = Gaudi::svcLocator()->getOptsSvc(); - const auto& configured_properties = jobOptionsSvc.items(); - for (const auto& per_property : configured_properties) { - // sample output: - // HepMCToEDMConverter.genparticles = "GenParticles"; - // Note that quotes are added to all property values, - // which leads to problems with ints, lists, dicts and bools. - // For these types, the quotes must be removed in postprocessing. - config_data.emplace_back(std::get<0>(per_property) + " = \"" + std::get<1>(per_property) + "\"\n"); - } - - // Collect all the metadata - podio::Frame config_metadata_frame{}; - config_metadata_frame.putParameter("gaudiConfigOptions", config_data); - if (const char* env_key4hep_stack = std::getenv("KEY4HEP_STACK")) { - std::string s_env_key4hep_stack = env_key4hep_stack; - config_metadata_frame.putParameter("key4hepstack", s_env_key4hep_stack); - } - m_framewriter->writeFrame(config_metadata_frame, "configuration_metadata"); - - auto& metadata_frame = m_podioDataSvc->getMetaDataFrame(); - m_framewriter->writeFrame(metadata_frame, "metadata"); - - // write information into file - m_framewriter->finish(); - - return StatusCode::SUCCESS; -} diff --git a/k4FWCore/components/PodioOutput.h b/k4FWCore/components/PodioOutput.h deleted file mode 100644 index 66f57207..00000000 --- a/k4FWCore/components/PodioOutput.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ -#ifndef FWCORE_PODIOOUTPUT_H -#define FWCORE_PODIOOUTPUT_H - -#include "Gaudi/Algorithm.h" -#include "k4FWCore/KeepDropSwitch.h" -#include "podio/ROOTWriter.h" - -#include - -// forward declarations -class PodioDataSvc; - -class [[deprecated("Use the IOSvc instead")]] PodioOutput : public Gaudi::Algorithm { -public: - /// Constructor. - PodioOutput(const std::string& name, ISvcLocator* svcLoc); - - /// Initialization of PodioOutput. Acquires the data service, creates trees and root file. - StatusCode initialize() override; - /// Execute. For the first event creates branches for all collections known to PodioDataSvc and prepares them for - /// writing. For the following events it reconnects the branches with collections and prepares them for write. - StatusCode execute(const EventContext&) const override; - /// Finalize. Writes the meta data tree; writes file and cleans up all ROOT-pointers. - StatusCode finalize() override; - -private: - /// First event or not - mutable bool m_firstEvent; - /// Root file name the output is written to - Gaudi::Property m_filename{this, "filename", "output.root", "Name of the file to create"}; - /// Commands which output is to be kept - Gaudi::Property> m_outputCommands{ - this, "outputCommands", {"keep *"}, "A set of commands to declare which collections to keep or drop."}; - Gaudi::Property m_filenameRemote{this, "remoteFilename", "", - "An optional file path to copy the outputfile to."}; - /// Switch for keeping or dropping outputs - k4FWCore::KeepDropSwitch m_switch; - PodioDataSvc* m_podioDataSvc; - /// The actual ROOT frame writer - std::unique_ptr m_framewriter; - /// The stored collections - std::vector m_storedCollections; - /// The collections to write out - mutable std::vector m_collection_names_to_write; -}; - -#endif diff --git a/k4FWCore/components/k4DataSvc.cpp b/k4FWCore/components/k4DataSvc.cpp deleted file mode 100644 index d5d0e490..00000000 --- a/k4FWCore/components/k4DataSvc.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 "k4DataSvc.h" - -// Instantiation of a static factory class used by clients to create -// instances of this service -DECLARE_COMPONENT(k4DataSvc) - -/// Standard Constructor -k4DataSvc::k4DataSvc(const std::string& name, ISvcLocator* svc) : PodioDataSvc(name, svc) { - declareProperty("inputs", m_filenames = {}, "Names of the files to read"); - declareProperty("input", m_filename = "", "Name of the file to read"); - declareProperty("FirstEventEntry", m_1stEvtEntry = 0, "First event to read"); -} diff --git a/k4FWCore/components/k4DataSvc.h b/k4FWCore/components/k4DataSvc.h deleted file mode 100644 index 65c93240..00000000 --- a/k4FWCore/components/k4DataSvc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -#ifndef K4FWCORE_K4DATASVC_H -#define K4FWCORE_K4DATASVC_H - -#include "k4FWCore/PodioDataSvc.h" - -class [[deprecated("Use the IOSvc instead")]] k4DataSvc : public PodioDataSvc { -public: - /// Standard Constructor - k4DataSvc(const std::string& name, ISvcLocator* svc); -}; -#endif diff --git a/k4FWCore/include/k4FWCore/MetaDataHandle.h b/k4FWCore/include/k4FWCore/MetaDataHandle.h deleted file mode 100644 index 2769fa8d..00000000 --- a/k4FWCore/include/k4FWCore/MetaDataHandle.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - */ -#ifndef K4FWCORE_METADATAHANDLE_H -#define K4FWCORE_METADATAHANDLE_H - -#include - -#include "k4FWCore/MetadataUtils.h" -#include "k4FWCore/PodioDataSvc.h" - -namespace k4FWCore { - -template -class [[deprecated("Use k4FWCore::putParameter / k4FWCore::getParameter from MetadataUtils.h instead")]] -MetaDataHandle { -public: - MetaDataHandle(const std::string& descriptor, Gaudi::DataHandle::Mode a); - MetaDataHandle(const Gaudi::DataHandle& handle, const std::string& descriptor, Gaudi::DataHandle::Mode a); - - /// Get the value that is stored in this MetaDataHandle - /// - /// @returns The value for this MetaDataHandle - /// - /// @throws GaudiException in case the value is not (yet) available - const T get() const; - - /// Get the (optional) value that is stored in this MetaDataHandle - /// - /// @returns An optional that contains the value if it was available from the - /// data store and is not engaged otherwise - std::optional get_optional() const; - - /// Get the value that is stored in the MetaDataHandle or the provided default - /// value in case that is not available - /// - /// @returns The value stored in the Handle or the default value - const T get(const T& defaultValue) const; - - /// Set the value for this MetaDataHandle - /// - /// @note This can only be called during initialize and/or finalize but not - /// during execute for algorithms that use it - void put(T); - -private: - std::string fullDescriptor() const; - - void checkPodioDataSvc(); - -private: - ServiceHandle m_eds; - std::string m_descriptor; - PodioDataSvc* m_podio_data_service{nullptr}; - const Gaudi::DataHandle* m_dataHandle{nullptr}; // holds the identifier in case we do collection metadata - Gaudi::DataHandle::Mode m_mode; -}; - -//--------------------------------------------------------------------------- -template -MetaDataHandle::MetaDataHandle(const std::string& descriptor, Gaudi::DataHandle::Mode a) - : m_eds("EventDataSvc", "DataHandle"), m_descriptor(descriptor), m_mode(a) { - m_eds.retrieve().ignore(); - m_podio_data_service = dynamic_cast(m_eds.get()); - checkPodioDataSvc(); -} - -//--------------------------------------------------------------------------- -template -MetaDataHandle::MetaDataHandle(const Gaudi::DataHandle& handle, const std::string& descriptor, - Gaudi::DataHandle::Mode a) - : m_eds("EventDataSvc", "DataHandle"), m_descriptor(descriptor), m_dataHandle(&handle), m_mode(a) { - m_eds.retrieve().ignore(); - m_podio_data_service = dynamic_cast(m_eds.get()); - checkPodioDataSvc(); -} - -//--------------------------------------------------------------------------- -template -std::optional MetaDataHandle::get_optional() const { - if (m_podio_data_service) { - return m_podio_data_service->getMetaDataFrame().getParameter(fullDescriptor()); - } - return k4FWCore::getParameter(fullDescriptor()); -} - -//--------------------------------------------------------------------------- -template -const T MetaDataHandle::get() const { - auto optional_parameter = get_optional(); - if (!optional_parameter.has_value()) { - throw GaudiException("MetaDataHandle empty handle access", - "MetaDataHandle " + fullDescriptor() + " not (yet?) available", StatusCode::FAILURE); - } - return optional_parameter.value(); -} - -//--------------------------------------------------------------------------- -template -const T MetaDataHandle::get(const T& defaultValue) const { - return get_optional().value_or(defaultValue); -} - -//--------------------------------------------------------------------------- -template -void MetaDataHandle::put(T value) { - if (m_mode != Gaudi::DataHandle::Writer) - throw GaudiException("MetaDataHandle policy violation", "Put for non-writing MetaDataHandle not allowed", - StatusCode::FAILURE); - // check whether we are in the proper State - // put is only allowed in the initialization - - std::string full_descriptor = fullDescriptor(); - // DataHandle based algorithms - if (m_podio_data_service) { - if (m_podio_data_service->targetFSMState() == Gaudi::StateMachine::RUNNING) { - throw GaudiException("MetaDataHandle policy violation", "Put cannot be used during the event loop", - StatusCode::FAILURE); - } - podio::Frame& frame = m_podio_data_service->getMetaDataFrame(); - frame.putParameter(full_descriptor, value); - // Functional algorithms - } else { - k4FWCore::putParameter(full_descriptor, value); - } -} - -//--------------------------------------------------------------------------- -template -std::string MetaDataHandle::fullDescriptor() const { - if (nullptr != m_dataHandle) { - auto full_descriptor = podio::collMetadataParamName(m_dataHandle->objKey(), m_descriptor); - // remove the "/Event/" part of the collections' object key if in read mode - if (m_mode == Gaudi::DataHandle::Reader && full_descriptor.find("/Event/") == 0u) { - full_descriptor.erase(0, 7); - } - return full_descriptor; - } - - return m_descriptor; -} - -//--------------------------------------------------------------------------- -template -void MetaDataHandle::checkPodioDataSvc() { - // do not do this check during the genconf step - const std::string cmd = System::cmdLineArgs()[0]; - if (cmd.find("genconf") != std::string::npos) - return; - - if (!m_podio_data_service && !Gaudi::svcLocator()->service("MetadataSvc", false)) { - std::cout << "Warning: MetaDataHandles require the PodioDataSvc or for compatibility the MetadataSvc" << std::endl; - } -} -} // namespace k4FWCore - -template -using MetaDataHandle [[deprecated("Use k4FWCore::MetaDataHandle instead")]] = k4FWCore::MetaDataHandle; - -#endif diff --git a/k4FWCore/include/k4FWCore/PodioDataSvc.h b/k4FWCore/include/k4FWCore/PodioDataSvc.h deleted file mode 100644 index 0da2591e..00000000 --- a/k4FWCore/include/k4FWCore/PodioDataSvc.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - */ -#ifndef FWCORE_PODIODATASVC_H -#define FWCORE_PODIODATASVC_H - -#include "GaudiKernel/DataSvc.h" -#include "GaudiKernel/IConversionSvc.h" -// PODIO -#include "podio/CollectionBase.h" -#include "podio/CollectionIDTable.h" -#include "podio/Frame.h" -#include "podio/ROOTReader.h" -#include -// Forward declarations -#include "k4FWCore/DataWrapper.h" -class DataWrapperBase; -class PodioOutput; -namespace k4FWCore { -template -class MetaDataHandle; -} - -/** @class PodioEvtSvc EvtDataSvc.h - * - * An EvtDataSvc for PODIO classes - * - * @author B. Hegner - */ -class [[deprecated("Use the IOSvc instead")]] PodioDataSvc : public DataSvc { - template - friend class k4FWCore::MetaDataHandle; - friend class PodioOutput; - friend class Lcio2EDM4hepTool; - -public: - typedef std::vector> CollRegistry; - - StatusCode initialize() final; - StatusCode reinitialize() final; - StatusCode finalize() final; - StatusCode clearStore() final; - StatusCode i_setRoot(std::string root_path, IOpaqueAddress* pRootAddr) final; - StatusCode i_setRoot(std::string root_path, DataObject* pRootObj) final; - - /// Standard Constructor - PodioDataSvc(const std::string& name, ISvcLocator* svc); - - // Use DataSvc functionality except where we override - using DataSvc::registerObject; - /// Overriding standard behaviour of evt service - /// Register object with the data store. - StatusCode registerObject(std::string_view parentPath, std::string_view fullPath, DataObject* pObject) final; - - 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) { - error() << "Collection " << collName << " does not exist." << endmsg; - } - auto wrapper = new DataWrapper; - wrapper->setData(collection); - m_podio_datawrappers.push_back(wrapper); - return DataSvc::registerObject("/Event", "/" + collName, wrapper); - } - - const podio::Frame& getEventFrame() const { return m_eventframe; } - - /// Resets caches of reader and event store, increases event counter - void endOfRead(); - - /// TODO: Make this private again after conversions have been properly solved - podio::Frame& getMetaDataFrame() { return m_metadataframe; } - - void setCollsToRead(const std::vector& collsToRead) { m_collsToRead = collsToRead; } - -private: - /// PODIO reader for ROOT files - podio::ROOTReader m_reader; - /// PODIO Frame, used to initialise collections - podio::Frame m_eventframe; - /// PODIO Frame, used to store metadata - podio::Frame m_metadataframe; - /// Counter of the event number - int m_eventNum{0}; - /// Number of events in the file / to process - int m_numAvailableEvents{-1}; - int m_requestedEventMax{-1}; - /// Whether reading from file at all - bool m_reading_from_file{false}; - - SmartIF m_cnvSvc; - - // Registry of data wrappers; needed for memory management - std::vector m_podio_datawrappers; - /// The names of the collections to read (set externally) - std::vector m_collsToRead{}; - -protected: - /// ROOT file name the input is read from. Set by option filename - std::vector m_filenames; - std::string m_filename; - /// Jump to nth events at the beginning. Set by option FirstEventEntry - /// This option is helpful when we want to debug an event in the middle of a file - unsigned m_1stEvtEntry{0}; - bool m_bounds_check_needed{true}; -}; -#endif // CORE_PODIODATASVC_H diff --git a/k4FWCore/src/PodioDataSvc.cpp b/k4FWCore/src/PodioDataSvc.cpp deleted file mode 100644 index c3990c4f..00000000 --- a/k4FWCore/src/PodioDataSvc.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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 "k4FWCore/PodioDataSvc.h" -#include "GaudiKernel/IEventProcessor.h" -#include "GaudiKernel/IProperty.h" -#include "GaudiKernel/ISvcLocator.h" -#include "k4FWCore/DataWrapper.h" -#include - -#include "podio/CollectionBase.h" -#include "podio/podioVersion.h" - -/// Service initialisation -StatusCode PodioDataSvc::initialize() { - warning() << "The PodioDataSvc is deprecated and will be removed. Use the IOSvc instead" << endmsg; - // Nothing to do: just call base class initialisation - StatusCode status = DataSvc::initialize(); - ISvcLocator* svc_loc = serviceLocator(); - - // Attach data loader facility - m_cnvSvc = svc_loc->service("EventPersistencySvc"); - status = setDataLoader(m_cnvSvc); - - if (!m_filename.empty()) { - m_filenames.push_back(m_filename); - } - - if (!m_filenames.empty()) { - if (!m_filenames[0].empty()) { - m_reading_from_file = true; - m_reader.openFiles(m_filenames); - m_numAvailableEvents = m_reader.getEntries("events"); - m_numAvailableEvents -= m_1stEvtEntry; - } - } - - if (m_reading_from_file) { - if (auto metadata = m_reader.readEntry("metadata", 0)) { - m_metadataframe = std::move(metadata); - } else { - warning() << "Reading file without a 'metadata' category." << endmsg; - m_metadataframe = podio::Frame(); - } - } else { - m_metadataframe = podio::Frame(); - } - - auto appMgr = service("ApplicationMgr", false); - if (!appMgr) { - throw std::runtime_error("Could not get ApplicationMgr"); - } - Gaudi::Property evtMax; - evtMax.assign(appMgr->getProperty("EvtMax")); - m_requestedEventMax = evtMax; - m_requestedEventMax -= m_1stEvtEntry; - - // if run with a fixed number of requested events and we have enough - // in the file we don't need to check if we run out of events - if (m_requestedEventMax > 0 && m_requestedEventMax <= m_numAvailableEvents) { - m_bounds_check_needed = false; - } - - return status; -} -/// Service reinitialisation -StatusCode PodioDataSvc::reinitialize() { - // Do nothing for this service - return StatusCode::SUCCESS; -} -/// Service finalization -StatusCode PodioDataSvc::finalize() { - warning() << "The PodioDataSvc is deprecated and will be removed. Use the IOSvc instead" << endmsg; - m_cnvSvc = nullptr; // release - DataSvc::finalize().ignore(); - return StatusCode::SUCCESS; -} - -StatusCode PodioDataSvc::clearStore() { - // as the frame takes care of the ownership of the podio::Collections, - // make sure the DataWrappers don't cause a double delete - for (auto wrapper : m_podio_datawrappers) { - wrapper->resetData(); - } - m_podio_datawrappers.clear(); - - DataSvc::clearStore().ignore(); - return StatusCode::SUCCESS; -} - -StatusCode PodioDataSvc::i_setRoot(std::string root_path, IOpaqueAddress* pRootAddr) { - // create a new frame - if (m_reading_from_file) { - debug() << "Reading event " << m_eventNum + m_1stEvtEntry << ", using collections: " << m_collsToRead << endmsg; -#if PODIO_BUILD_VERSION <= PODIO_VERSION(1, 2, 0) - if (!m_collsToRead.empty()) { - warning() << "Trying to limit collections that are read, but podio does only support this with version > 1.2" - << endmsg; - } - m_eventframe = podio::Frame(m_reader.readEntry("events", m_eventNum + m_1stEvtEntry)); -#else - m_eventframe = podio::Frame(m_reader.readEntry("events", m_eventNum + m_1stEvtEntry, m_collsToRead)); -#endif - } else { - m_eventframe = podio::Frame(); - } - return DataSvc::i_setRoot(root_path, pRootAddr); -} - -StatusCode PodioDataSvc::i_setRoot(std::string root_path, DataObject* pRootObj) { - // create a new frame - if (m_reading_from_file) { - debug() << "Reading event " << m_eventNum + m_1stEvtEntry << ", using collections: " << m_collsToRead << endmsg; -#if PODIO_BUILD_VERSION <= PODIO_VERSION(1, 2, 0) - if (!m_collsToRead.empty()) { - warning() << "Trying to limit collections that are read, but podio does only support this with version > 1.2" - << endmsg; - } - m_eventframe = podio::Frame(m_reader.readEntry("events", m_eventNum + m_1stEvtEntry)); -#else - m_eventframe = podio::Frame(m_reader.readEntry("events", m_eventNum + m_1stEvtEntry, m_collsToRead)); -#endif - } else { - m_eventframe = podio::Frame(); - } - return DataSvc::i_setRoot(root_path, pRootObj); -} - -void PodioDataSvc::endOfRead() { - m_eventNum++; - - if (!m_bounds_check_needed) { - return; - } - - StatusCode sc; - // m_eventNum already points to the next event here so check if it is available - if (m_eventNum >= m_numAvailableEvents) { - info() << "Reached end of file with event " << m_eventNum << " (" << m_requestedEventMax << " events requested)" - << endmsg; - auto eventProcessor = service("ApplicationMgr", false); - if (!eventProcessor) { - throw std::runtime_error("Could not retrieve ApplicationMgr to schedule a stop"); - } - sc = eventProcessor->stopRun(); - if (sc.isFailure()) { - throw std::runtime_error("Failed to stop the run"); - } - } -} - -/// Standard Constructor -PodioDataSvc::PodioDataSvc(const std::string& name, ISvcLocator* svc) : DataSvc(name, svc) {} - -const std::string_view PodioDataSvc::getCollectionType(const std::string& collName) { - const auto coll = m_eventframe.get(collName); - if (coll == nullptr) { - error() << "Collection " << collName << " does not exist." << endmsg; - return ""; - } - return coll->getTypeName(); -} - -StatusCode PodioDataSvc::registerObject(std::string_view parentPath, std::string_view fullPath, DataObject* pObject) { - auto* wrapper = dynamic_cast(pObject); - if (wrapper != nullptr) { - podio::CollectionBase* coll = wrapper->collectionBase(); - if (coll != nullptr) { - size_t pos = fullPath.find_last_of("/"); - std::string shortPath(fullPath.substr(pos + 1, fullPath.length())); - // Attention: this passes the ownership of the data to the frame - m_eventframe.put(std::unique_ptr(coll), shortPath); - m_podio_datawrappers.push_back(wrapper); - } - } - return DataSvc::registerObject(parentPath, fullPath, pObject); -} From 96d96516b158941991dde81f62ce87715e1ced59 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 15:10:02 +0200 Subject: [PATCH 03/16] Remove documentation of legacy I/O system --- doc/LegacyPodioInputOutput.md | 136 ---------------------------------- 1 file changed, 136 deletions(-) delete mode 100644 doc/LegacyPodioInputOutput.md diff --git a/doc/LegacyPodioInputOutput.md b/doc/LegacyPodioInputOutput.md deleted file mode 100644 index 5c1d24d9..00000000 --- a/doc/LegacyPodioInputOutput.md +++ /dev/null @@ -1,136 +0,0 @@ - -# Legacy reading and writing EDM4hep files in Gaudi with the 4DataSvc - -:::{caution} -`k4DataSvc` is a legacy service previously used in K4FWCore for reading and writing data in EDM4hep or other data models based on PODIO. - -The currently used service is `IOSvc`, which offers improved streamlined functionality and better support for modern workflows. For detailed documentation on `IOSvc`, refer to [this documentation](PodioInputOutput.md). -::: - -This page will describe the usage of legacy [k4FWCore](https://github.com/key4hep/k4FWCore) -facilities to read and write EDM4hep. This page also assumes a certain -familiarity with Gaudi, i.e. most of the snippets just show a minimal -configuration part, and not a complete runnable example. - -## The `k4DataSvc` - -Whenever you want to work with EDM4hep in the Gaudi based framework of Key4hep, -you will need to use the `k4DataSvc` as *EventDataSvc*. You can instantiate and -configure this service like the following - -```python -from Gaudi.Configuration import * -from Configurables import k4DataSvc - -evtSvc = k4DataSvc("EventDataSvc") -``` - -**It is important that the name is `EventDataSvc` in this case, as otherwise -this is an assumption from Gaudi.** Once you have the `k4DataSvc` instantiated, -you still have to make the `ApplicationMgr` aware of it, by making sure that the -`evtSvc` is in the list of the *external services* (`ExtSvc`): - -```python -from Configurables import ApplicationMgr -ApplicationMgr( - # other args - ExtSvc = [evtSvc] -) -``` - -## Reading events - -To read events you will need to use the `PodioInput` algorithm in addition to -the [`k4DataSvc`](#the-k4datasvc). Currently, you will need to pass the input -file to the `k4DataSvc` via the `input` option but pass the collections that you -want to read to the `PodioInput`. We are working on making this (discussion -happens in this [issue](https://github.com/key4hep/k4FWCore/issues/105)). The -parts of your options file related to reading EDM4hep files will look something -like this - -```python -from Configurables import PodioInput, k4DataSvc - -evtSvc = k4DataSvc("EventDataSvc") -evtSvc.input = "/path/to/your/input-file.root" - -podioInput = PodioInput() -``` - -It is possible to change the input file from the command line via -```bash -k4run --EventDataSvc.input= -``` - -By default the `PodioInput` will read all collections that are available from -the input file. It is possible to limit the collections that should become -available via the `collections` option - -```python -podioInput.collections = [ - # List of collection names that should be made available -] -``` - -## Writing events - -To write events you will need to use the `PodioOutput` algorithm in addition to -the [`k4DataSvc`](#the-k4datasvc): - -```python -from Configurables import PodioOutput - -podioOutput = PodioOutput("PodioOutput", filename="my_output.root") -``` - -By default this will write the complete event contents to the output file. - -### Writing only a subset of collections - -Sometimes it is desirable to limit the collections to a subset of all available -collections from the EventStore. The `PodioOutput` allows to do this via the -`outputCommands` option that takes a list of `keep` or `drop` commands. Each -command must consist of the `keep`/`drop` command and a target. The target is a -collection name that may include the `?` or `*` wildcard patterns. This might -look like the following - -```python -podioOutput.outputCommands = ["keep *"] -``` - -which will keep everything (the default), while - -```python -podioOutput.outputCommands = ["drop *"] -``` - -will simply drop all collections and effectively write an empty file (apart from -some metadata). A common pattern is to `"drop *"` and then selectively adding -`keep` collections to keep, e.g. to only keep the highest level MC and reco -information: - -```python -podioOutput.outputCommands = [ - "drop *", - "keep MCParticlesSkimmed", - "keep PandoraPFOs", - "keep RecoMCTruthLink", -] -``` From e23e77ba98e6cf1abf9a906023ac5dd33e291b25 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 15:21:00 +0200 Subject: [PATCH 04/16] Don't use legacy data svc for tests --- test/k4FWCoreTest/options/TestUniqueIDGenSvc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/k4FWCoreTest/options/TestUniqueIDGenSvc.py b/test/k4FWCoreTest/options/TestUniqueIDGenSvc.py index d0b71ea0..5396433f 100644 --- a/test/k4FWCoreTest/options/TestUniqueIDGenSvc.py +++ b/test/k4FWCoreTest/options/TestUniqueIDGenSvc.py @@ -20,7 +20,7 @@ from Configurables import UniqueIDGenSvc from k4FWCore import ApplicationMgr -from Configurables import k4DataSvc +from Configurables import EventDataSvc from Configurables import TestUniqueIDGenSvc uid_svc = UniqueIDGenSvc(Seed=987, CheckDuplicates=True) @@ -30,8 +30,8 @@ ApplicationMgr().OutputLevel = INFO ApplicationMgr().StopOnSignal = True -podioevent = k4DataSvc("EventDataSvc") -ApplicationMgr().ExtSvc += [podioevent] +evtDataSvc = EventDataSvc("EventDataSvc") +ApplicationMgr().ExtSvc += [evtDataSvc] uniqueidtest = TestUniqueIDGenSvc() From 49f1e06031cbee1a66f5f1ca119d1f89d11ca6f9 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 15:22:36 +0200 Subject: [PATCH 05/16] Remove option to run with legacy I/O components --- test/k4FWCoreTest/CMakeLists.txt | 1 - test/k4FWCoreTest/options/runFunctionalMix.py | 52 +++---------------- 2 files changed, 7 insertions(+), 46 deletions(-) diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 49c3b5da..3565feee 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -206,7 +206,6 @@ add_test_fwcore(FunctionalSeveralInputFiles options/ExampleFunctionalSeveralInpu add_test_fwcore(FunctionalMTFile options/ExampleFunctionalMTFile.py PROPERTIES FIXTURES_REQUIRED ProducerMultipleFile ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMultipleFile options/ExampleFunctionalFileMultiple.py PROPERTIES FIXTURES_REQUIRED ProducerMultipleFile ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMix options/runFunctionalMix.py PROPERTIES FIXTURES_REQUIRED ProducerMultipleFile ADD_TO_CHECK_FILES) -add_test_fwcore(FunctionalMixIOSvc options/runFunctionalMix.py --iosvc PROPERTIES FIXTURES_REQUIRED ProducerMultipleFile ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalOutputCommands options/ExampleFunctionalOutputCommands.py PROPERTIES FIXTURES_REQUIRED ProducerMultipleFile ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalConsumerRuntimeCollections options/ExampleFunctionalConsumerRuntimeCollections.py) add_test_fwcore(FunctionalConsumerRuntimeCollectionsMultiple options/ExampleFunctionalConsumerRuntimeCollectionsMultiple.py) diff --git a/test/k4FWCoreTest/options/runFunctionalMix.py b/test/k4FWCoreTest/options/runFunctionalMix.py index 7e995c3e..747c7ac7 100644 --- a/test/k4FWCoreTest/options/runFunctionalMix.py +++ b/test/k4FWCoreTest/options/runFunctionalMix.py @@ -30,47 +30,11 @@ k4FWCoreTest_CreateExampleEventData, ) from Configurables import k4FWCoreTest_CheckExampleEventData -from k4FWCore import ApplicationMgr -from Configurables import k4DataSvc -from Configurables import PodioInput, PodioOutput -from k4FWCore.parseArgs import parser - -parser.add_argument( - "--iosvc", - help="Use the IOSvc instead of PodioInput and PodioOutput", - action="store_true", - default=False, -) -args = parser.parse_known_args()[0] - -print(args.iosvc) - -if not args.iosvc: - podioevent = k4DataSvc("EventDataSvc") - podioevent.input = "functional_producer_multiple.root" - - inp = PodioInput() - inp.collections = [ - "VectorFloat", - "MCParticles1", - "MCParticles2", - "SimTrackerHits", - "TrackerHits", - "Tracks", - "RecoParticles", - "Links", - ] - - out = PodioOutput() - out.filename = "functional_mix.root" - out.outputCommands = ["keep *"] - -else: - from k4FWCore import IOSvc, ApplicationMgr +from k4FWCore import ApplicationMgr, IOSvc - iosvc = IOSvc("IOSvc") - iosvc.Input = "functional_producer_multiple.root" - iosvc.Output = "functional_mix_iosvc.root" +iosvc = IOSvc("IOSvc") +iosvc.Input = "functional_producer_multiple.root" +iosvc.Output = "functional_mix_iosvc.root" # Check input with functional and old algorithms @@ -153,8 +117,7 @@ ApplicationMgr( - TopAlg=([inp] if not args.iosvc else []) - + [ + TopAlg=[ # Check we can read input consumer_input_functional, consumer_input_algorithm, @@ -167,10 +130,9 @@ consumer_produceralg_functional, consumer_produceralg_algorithm, transformer_functional, - ] - + ([out] if not args.iosvc else []), + ], EvtSel="NONE", EvtMax=10, - ExtSvc=[iosvc if args.iosvc else podioevent], + ExtSvc=[iosvc], OutputLevel=INFO, ) From ec6d496f3d2c3a866d398a628bbf679bd3fb583a Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 15:55:07 +0200 Subject: [PATCH 06/16] Remove test cases which no longer make sense Equivalent functionality for IOSvc covered by other test cases --- test/k4FWCoreTest/CMakeLists.txt | 2 - .../readLimitedSetOfCollectionsk4DataSvc.py | 38 ------------------- 2 files changed, 40 deletions(-) delete mode 100644 test/k4FWCoreTest/options/readLimitedSetOfCollectionsk4DataSvc.py diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 3565feee..f84e84e6 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -140,8 +140,6 @@ add_test_fwcore(CheckExampleEventData_unbounded options/checkExampleEventData.py add_test_fwcore(ReadExampleEventData options/readExampleEventData.py) set_property(TEST ReadExampleEventData APPEND PROPERTY FIXTURES_REQUIRED ExampleEventDataFile) add_test_fwcore(ReadExampleDataFromNthEvent options/readExampleDataFromNthEvent.py PROPERTIES FIXTURES_REQUIRED ExampleEventDataFile) -add_test_fwcore(ReadLimitedInputsk4DataSvc options/readLimitedSetOfCollectionsk4DataSvc.py ADD_TO_CHECK_FILES PROPERTIES FIXTURES_REQUIRED ExampleEventDataFile) -add_test_fwcore(ReadLimitedInputsAllEventsk4DataSvc options/readLimitedSetOfCollectionsk4DataSvc.py -n -1 --PodioOutput.filename "output_k4test_exampledata_limited_allevents.root" ADD_TO_CHECK_FILES PROPERTIES FIXTURES_REQUIRED ExampleEventDataFile) add_test_fwcore(AlgorithmWithTFile options/TestAlgorithmWithTFile.py PROPERTIES FIXTURES_SETUP AlgorithmWithTFileFixture) set_property(TEST AlgorithmWithTFile PROPERTY WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) diff --git a/test/k4FWCoreTest/options/readLimitedSetOfCollectionsk4DataSvc.py b/test/k4FWCoreTest/options/readLimitedSetOfCollectionsk4DataSvc.py deleted file mode 100644 index ea8e6661..00000000 --- a/test/k4FWCoreTest/options/readLimitedSetOfCollectionsk4DataSvc.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. -# -from Gaudi.Configuration import DEBUG -from Configurables import k4DataSvc -from Configurables import PodioInput -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr - -podioevent = k4DataSvc("EventDataSvc") -podioevent.input = "output_k4test_exampledata.root" -podioevent.OutputLevel = DEBUG - -inp = PodioInput() -inp.collections = ["MCParticles", "Links"] - -output = PodioOutput() -output.filename = "output_k4test_exampledata_limited.root" - -ApplicationMgr( - TopAlg=[inp, output], EvtSel="NONE", EvtMax=5, ExtSvc=[podioevent], OutputLevel=DEBUG -) From ef1a5db2f3ee611b1a4629f93e0541635c6ba8b8 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 16:02:50 +0200 Subject: [PATCH 07/16] Switch tests over to IOSvc and EventDataSvc --- test/k4FWCoreTest/CMakeLists.txt | 2 +- .../options/TestAlgorithmWithTFile.py | 21 ++++++--------- test/k4FWCoreTest/options/TwoProducers.py | 18 +++++-------- .../options/checkExampleEventData.py | 17 +++++------- .../k4FWCoreTest/options/createEventHeader.py | 24 +++++------------ .../options/createExampleEventData.py | 20 +++++--------- .../createExampleEventDataInDirectory.py | 18 +++++-------- .../options/createExampleEventData_cellID.py | 23 ++++++++-------- .../options/readExampleDataFromNthEvent.py | 26 +++++++------------ .../options/readExampleEventData.py | 26 +++++++------------ 10 files changed, 73 insertions(+), 122 deletions(-) diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index f84e84e6..72ad3c72 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -153,7 +153,7 @@ add_test(NAME AlgorithmWithTFileCheckMyTFileOutput set_property(TEST AlgorithmWithTFileCheckMyTFileOutput APPEND PROPERTY FIXTURES_REQUIRED AlgorithmWithTFileFixture) add_test_fwcore(CreateExampleEventData_cellID options/createExampleEventData_cellID.py ADD_TO_CHECK_FILES) -add_test_fwcore(TwoProducers options/TwoProducers.py --filename output_k4fwcore_test_twoproducer.root +add_test_fwcore(TwoProducers options/TwoProducers.py --magicNumberOffset.Producer2 12345 --Producer1.magicNumberOffset 54321) add_test_fwcore(CheckCommandLineArguments options/createHelloWorld.py --HelloWorldAlg1.PerEventPrintMessage TwasBrilligAndTheSlithyToves PROPERTIES PASS_REGULAR_EXPRESSION "TwasBrilligAndTheSlithyToves" diff --git a/test/k4FWCoreTest/options/TestAlgorithmWithTFile.py b/test/k4FWCoreTest/options/TestAlgorithmWithTFile.py index b1046bb5..55cdcb9b 100644 --- a/test/k4FWCoreTest/options/TestAlgorithmWithTFile.py +++ b/test/k4FWCoreTest/options/TestAlgorithmWithTFile.py @@ -16,29 +16,24 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from Gaudi.Configuration import * +from Gaudi.Configuration import INFO -from Configurables import k4DataSvc -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr -from Configurables import k4FWCoreTest_AlgorithmWithTFile - -podioevent = k4DataSvc("EventDataSvc") +from k4FWCore import ApplicationMgr, IOSvc +from Configurables import k4FWCoreTest_AlgorithmWithTFile, EventDataSvc producer = k4FWCoreTest_AlgorithmWithTFile() - -out = PodioOutput("out") -out.filename = "output_TestAlgorithmWithTFile_framework.root" -out.outputCommands = ["keep *"] +iosvc = IOSvc() +iosvc.Output = "output_TestAlgorithmWithTFile_framework.root" +iosvc.outputCommands = ["keep *"] ApplicationMgr( - TopAlg=[producer, out], + TopAlg=[producer], EvtSel="NONE", EvtMax=100, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc("EventDataSvc")], OutputLevel=INFO, StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/TwoProducers.py b/test/k4FWCoreTest/options/TwoProducers.py index 17e3507c..001b46bb 100644 --- a/test/k4FWCoreTest/options/TwoProducers.py +++ b/test/k4FWCoreTest/options/TwoProducers.py @@ -18,10 +18,13 @@ # from Gaudi.Configuration import INFO -from k4FWCore import ApplicationMgr -from Configurables import k4DataSvc +from k4FWCore import ApplicationMgr, IOSvc +from Configurables import EventDataSvc from Configurables import k4FWCoreTest_CreateExampleEventData -from Configurables import PodioOutput + +iosvc = IOSvc() +iosvc.Output = "output_k4test_exampledata_twoproducer.root" +iosvc.outputCommands = ["keep *"] ApplicationMgr( EvtSel="NONE", @@ -31,8 +34,7 @@ ) -podioevent = k4DataSvc("EventDataSvc") -ApplicationMgr().ExtSvc += [podioevent] +ApplicationMgr().ExtSvc += [EventDataSvc("EventDataSvc")] producer1 = k4FWCoreTest_CreateExampleEventData("Producer1") @@ -48,9 +50,3 @@ producer2.recoparticles.Path = "recoparticles2" producer2.links.Path = "links" ApplicationMgr().TopAlg += [producer2] - - -out = PodioOutput("out") -out.filename = "output_k4test_exampledata_twoproducer.root" -out.outputCommands = ["keep *"] -ApplicationMgr().TopAlg += [out] diff --git a/test/k4FWCoreTest/options/checkExampleEventData.py b/test/k4FWCoreTest/options/checkExampleEventData.py index 36572d3e..fccc6557 100644 --- a/test/k4FWCoreTest/options/checkExampleEventData.py +++ b/test/k4FWCoreTest/options/checkExampleEventData.py @@ -19,14 +19,11 @@ # from Gaudi.Configuration import INFO -from Configurables import k4DataSvc -from Configurables import PodioInput +from Configurables import EventDataSvc from k4FWCore.parseArgs import parser from Configurables import k4FWCoreTest_CheckExampleEventData -from k4FWCore import ApplicationMgr +from k4FWCore import ApplicationMgr, IOSvc -podioevent = k4DataSvc("EventDataSvc") -podioevent.input = "output_k4test_exampledata.root" parser.add_argument( "--collections", @@ -37,17 +34,17 @@ ) my_args = parser.parse_known_args()[0] -inp = PodioInput() -inp.collections = my_args.collections - +iosvc = IOSvc() +iosvc.Input = "output_k4test_exampledata.root" +iosvc.CollectionNames = my_args.collections checker = k4FWCoreTest_CheckExampleEventData() ApplicationMgr( - TopAlg=[inp, checker], + TopAlg=[checker], EvtSel="NONE", EvtMax=100, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], OutputLevel=INFO, StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/createEventHeader.py b/test/k4FWCoreTest/options/createEventHeader.py index 20993b97..d3d77754 100644 --- a/test/k4FWCoreTest/options/createEventHeader.py +++ b/test/k4FWCoreTest/options/createEventHeader.py @@ -16,13 +16,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from Gaudi.Configuration import * +from Gaudi.Configuration import DEBUG -from Configurables import EventHeaderCreator -from Configurables import k4DataSvc -from Configurables import PodioOutput -from Configurables import ExampleRNGSeedingAlg -from k4FWCore import ApplicationMgr +from Configurables import EventHeaderCreator, ExampleRNGSeedingAlg, EventDataSvc +from k4FWCore import ApplicationMgr, IOSvc eventHeaderCreator = EventHeaderCreator( "eventHeaderCreator", runNumber=42, eventNumberOffset=42, OutputLevel=DEBUG @@ -31,21 +28,14 @@ # algorithm using the header to seed a prng rngAlg = ExampleRNGSeedingAlg("ExampleRNGSeedingAlg") -podioevent = k4DataSvc("EventDataSvc") - - -out = PodioOutput("out") -out.filename = "eventHeader.root" +iosvc = IOSvc() +iosvc.Output = "eventHeader.root" ApplicationMgr( - TopAlg=[ - eventHeaderCreator, - rngAlg, - out, - ], + TopAlg=[eventHeaderCreator, rngAlg], EvtSel="NONE", EvtMax=2, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/createExampleEventData.py b/test/k4FWCoreTest/options/createExampleEventData.py index fe4e10fa..71d10d76 100644 --- a/test/k4FWCoreTest/options/createExampleEventData.py +++ b/test/k4FWCoreTest/options/createExampleEventData.py @@ -18,27 +18,21 @@ # from Gaudi.Configuration import INFO -from Configurables import k4DataSvc +from Configurables import EventDataSvc from Configurables import k4FWCoreTest_CreateExampleEventData -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr - -podioevent = k4DataSvc("EventDataSvc") +from k4FWCore import ApplicationMgr, IOSvc +iosvc = IOSvc() +iosvc.Output = "output_k4test_exampledata.root" +iosvc.outputCommands = ["keep *"] producer = k4FWCoreTest_CreateExampleEventData() - -out = PodioOutput("out") -out.filename = "output_k4test_exampledata.root" -out.outputCommands = ["keep *"] - - ApplicationMgr( - TopAlg=[producer, out], + TopAlg=[producer], EvtSel="NONE", EvtMax=100, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], OutputLevel=INFO, StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/createExampleEventDataInDirectory.py b/test/k4FWCoreTest/options/createExampleEventDataInDirectory.py index 691f55fa..c679be51 100644 --- a/test/k4FWCoreTest/options/createExampleEventDataInDirectory.py +++ b/test/k4FWCoreTest/options/createExampleEventDataInDirectory.py @@ -17,25 +17,21 @@ # limitations under the License. # from Gaudi.Configuration import INFO -from k4FWCore import ApplicationMgr -from Configurables import k4FWCoreTest_CreateExampleEventData -from Configurables import k4DataSvc -from Configurables import PodioOutput - -podioevent = k4DataSvc("EventDataSvc") +from k4FWCore import ApplicationMgr, IOSvc +from Configurables import k4FWCoreTest_CreateExampleEventData, EventDataSvc producer = k4FWCoreTest_CreateExampleEventData() -out = PodioOutput("out") -out.filename = "output/dir/output_k4test_exampledata.root" -out.outputCommands = ["keep *"] +iosvc = IOSvc() +iosvc.Output = "output/dir/output_k4test_exampledata.root" +iosvc.outputCommands = ["keep *"] ApplicationMgr( - TopAlg=[producer, out], + TopAlg=[producer], EvtSel="NONE", EvtMax=100, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], OutputLevel=INFO, StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/createExampleEventData_cellID.py b/test/k4FWCoreTest/options/createExampleEventData_cellID.py index f8c78e04..7c81754b 100644 --- a/test/k4FWCoreTest/options/createExampleEventData_cellID.py +++ b/test/k4FWCoreTest/options/createExampleEventData_cellID.py @@ -16,18 +16,18 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from Gaudi.Configuration import INFO +from Gaudi.Configuration import INFO, DEBUG -from Configurables import k4DataSvc from Configurables import ( k4FWCoreTest_cellID_writer, k4FWCoreTest_cellID_reader, MetadataSvc, + EventDataSvc, ) -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr +from k4FWCore import ApplicationMgr, IOSvc -podioevent = k4DataSvc("EventDataSvc") +evtDataSvc = EventDataSvc("EventDataSvc") +evtDataSvc.OutputLevel = DEBUG producer = k4FWCoreTest_cellID_writer( @@ -40,20 +40,19 @@ vectorFloatProp2=[1.1, 2.2, 3.3, 4.4], vectorDoubleProp2=[1.1, 2.2, 3.3, 4.4], vectorStringProp2=["one", "two", "three", "four"], + OutputLevel=DEBUG, ) consumer = k4FWCoreTest_cellID_reader() - -out = PodioOutput("out") -out.filename = "output_k4test_exampledata_cellid.root" -out.outputCommands = ["keep *"] - +iosvc = IOSvc() +iosvc.Input = "output_k4test_exampledata_cellid.root" +iosvc.outputCommands = ["keep *"] ApplicationMgr( - TopAlg=[producer, consumer, out], + TopAlg=[producer, consumer], EvtSel="NONE", EvtMax=10, - ExtSvc=[podioevent, MetadataSvc()], + ExtSvc=[evtDataSvc, MetadataSvc()], OutputLevel=INFO, StopOnSignal=True, ) diff --git a/test/k4FWCoreTest/options/readExampleDataFromNthEvent.py b/test/k4FWCoreTest/options/readExampleDataFromNthEvent.py index 6fd41518..2d1a0441 100644 --- a/test/k4FWCoreTest/options/readExampleDataFromNthEvent.py +++ b/test/k4FWCoreTest/options/readExampleDataFromNthEvent.py @@ -18,28 +18,20 @@ # from Gaudi.Configuration import DEBUG -from Configurables import k4DataSvc -from Configurables import PodioInput -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr +from Configurables import EventDataSvc +from k4FWCore import ApplicationMgr, IOSvc -podioevent = k4DataSvc("EventDataSvc") -podioevent.input = "output_k4test_exampledata.root" -podioevent.FirstEventEntry = 66 - - -inp = PodioInput() -inp.collections = ["MCParticles", "SimTrackerHits", "Tracks"] - - -oup = PodioOutput() -oup.filename = "output_k4test_exampledata_3.root" +iosvc = IOSvc() +iosvc.Input = "output_k4test_exampledata.root" +iosvc.FirstEventEntry = 66 +iosvc.CollectionNames = ["MCParticles", "SimTrackerHits", "Tracks"] +iosvc.Output = "output_k4test_exampledata_3.root" ApplicationMgr( - TopAlg=[inp, oup], + TopAlg=[], EvtSel="NONE", EvtMax=5, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], OutputLevel=DEBUG, ) diff --git a/test/k4FWCoreTest/options/readExampleEventData.py b/test/k4FWCoreTest/options/readExampleEventData.py index 09bdb6df..21fa4cd7 100644 --- a/test/k4FWCoreTest/options/readExampleEventData.py +++ b/test/k4FWCoreTest/options/readExampleEventData.py @@ -18,28 +18,20 @@ # from Gaudi.Configuration import DEBUG -from Configurables import k4DataSvc -from Configurables import PodioInput -from Configurables import PodioOutput -from k4FWCore import ApplicationMgr +from Configurables import EventDataSvc +from k4FWCore import ApplicationMgr, IOSvc -podioevent = k4DataSvc("EventDataSvc") -podioevent.input = "output_k4test_exampledata.root" - - -inp = PodioInput() -inp.collections = ["MCParticles", "SimTrackerHits", "TrackerHits", "Tracks"] - - -oup = PodioOutput() -oup.filename = "output_k4test_exampledata_2.root" -oup.outputCommands = ["drop MCParticles"] +iosvc = IOSvc +iosvc.Input = "output_k4test_exampledata.root" +iosvc.Output = "output_k4test_exampledata_2.root" +iosvc.CollectionNames = ["MCParticles", "SimTrackerHits", "TrackerHits", "Tracks"] +iosvc.outputCommands = ["drop MCParticles"] ApplicationMgr( - TopAlg=[inp, oup], + TopAlg=[], EvtSel="NONE", EvtMax=10, - ExtSvc=[podioevent], + ExtSvc=[EventDataSvc()], OutputLevel=DEBUG, ) From 2a02281af7196b6a4fce7eff5d55fb502e53a44d Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 20:48:06 +0200 Subject: [PATCH 08/16] Remove deprecated functions only used by removed MetadataHandle --- k4FWCore/include/k4FWCore/MetadataUtils.h | 27 ----------------------- 1 file changed, 27 deletions(-) diff --git a/k4FWCore/include/k4FWCore/MetadataUtils.h b/k4FWCore/include/k4FWCore/MetadataUtils.h index 2b527108..2e09dfe3 100644 --- a/k4FWCore/include/k4FWCore/MetadataUtils.h +++ b/k4FWCore/include/k4FWCore/MetadataUtils.h @@ -73,20 +73,6 @@ void putParameter(const std::string& name, const T& value, const GaudiComp* comp metadataSvc->template put(name, value); } -/// @brief Save a metadata parameter in the metadata frame. Overload for compatibility -/// with the MetadataHandle, don't use! -/// @deprecated Use the overload taking a Gaudi::Algorithm* instead -template -[[deprecated("Use the overload taking a Gaudi::Algorithm* as third argument instead")]] void -putParameter(const std::string& name, const T& value) { - auto metadataSvc = Gaudi::svcLocator()->service("MetadataSvc", false); - if (!metadataSvc) { - std::cout << "MetadataSvc not found" << std::endl; - return; - } - return metadataSvc->put(name, value); -} - /// @brief Get a metadata parameter from the metadata frame /// @param name The name of the parameter /// @param comp The Gaudi component (algorithm, tool) that is retrieving the @@ -105,19 +91,6 @@ std::optional getParameter(const std::string& name, const GaudiComp* comp) { return metadataSvc->template get(name); } -/// @brief Get a metadata parameter from the metadata frame. Overload for compatibility -/// with the MetadataHandle, don't use! -/// @deprecated Use the overload taking a Gaudi::Algorithm* instead -template -[[deprecated("Use the overload taking a Gaudi::Algorithm* as second argument instead")]] std::optional -getParameter(const std::string& name) { - auto metadataSvc = Gaudi::svcLocator()->service("MetadataSvc", false); - if (!metadataSvc) { - return std::nullopt; - } - return metadataSvc->get(name); -} - /// @brief Put a metadata parameter associated with a collection into the metadata /// /// Internally builds the correct parameter name from the collection name and From cf33107772d50e7c28ecc3b52c3066b3dc710815 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Thu, 2 Apr 2026 21:48:10 +0200 Subject: [PATCH 09/16] Remove MetaDataHandle from top level README --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index fa1577a9..82b6e44f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ k4FWCore also provides the `k4run` script used to run Gaudi steering files. See | IOSvc | k4DataSvc | Service handling the PODIO types and collections | | Reader | PodioInput | Algorithm to read data from input files on disk. | | Writer | PodioOutput | Algorithm to write data to an output file on disk. | -| MetadataSvc | MetaDataHandle | Service/Handle handling user defined metadata | See the [documentation](doc/PodioInputOutput.md) for more information. From 9e19916de6b1be87ec4d24ef5d3ceb077f516b54 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Tue, 7 Apr 2026 21:37:10 +0200 Subject: [PATCH 10/16] Remove a few mentions of the legacy algorithms --- README.md | 15 ++++++--------- cmake/k4FWCoreConfig.cmake.in | 3 +-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 82b6e44f..78610889 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,12 @@ k4FWCore also provides the `k4run` script used to run Gaudi steering files. See ### Basic I/O -| Current | Legacy | Description | -|---------|--------|-| -| IOSvc | k4DataSvc | Service handling the PODIO types and collections | -| Reader | PodioInput | Algorithm to read data from input files on disk. | -| Writer | PodioOutput | Algorithm to write data to an output file on disk. | - -See the [documentation](doc/PodioInputOutput.md) for more information. - -### Auxiliary +| Name | Description | +|---------|-| +| IOSvc | Service handling the PODIO types and collections | +| Reader | Algorithm to read data from input files on disk. | +| Writer | Algorithm to write data to an output file on disk. | +| MetadataSvc | Service/Handle handling user defined metadata | ### Collection Merger diff --git a/cmake/k4FWCoreConfig.cmake.in b/cmake/k4FWCoreConfig.cmake.in index 02a13c49..01bb3885 100644 --- a/cmake/k4FWCoreConfig.cmake.in +++ b/cmake/k4FWCoreConfig.cmake.in @@ -2,8 +2,7 @@ # k4FWCore CMake Config # # Exported Targets -# - k4FWCore::k4FWCore The core library containing the PodioDataSvc -# and the KeepDropSwitch +# - k4FWCore::k4FWCore The core library # - k4FWCore::k4FWCorePlugins The plugin library for the core plugins # provided by k4FWCore. Includes all major # services for I/O and as well as some utility From 94b8c8050079871a647d972484c665aa971a1128 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Tue, 7 Apr 2026 21:37:30 +0200 Subject: [PATCH 11/16] Remove doc PdoioInputOutput.md --- doc/PodioInputOutput.md | 246 ---------------------------------------- 1 file changed, 246 deletions(-) delete mode 100644 doc/PodioInputOutput.md diff --git a/doc/PodioInputOutput.md b/doc/PodioInputOutput.md deleted file mode 100644 index c0259455..00000000 --- a/doc/PodioInputOutput.md +++ /dev/null @@ -1,246 +0,0 @@ - -# Reading and writing EDM4hep files in Gaudi - -The facilities to read and write EDM4hep (or in general event data models based on podio) are provided by [k4FWCore](https://github.com/key4hep/k4FWCore). This page will describe their usage, but not go into too much details of their internals. This page also assumes a certain familiarity with Gaudi, i.e. most of the snippets just show a minimal configuration part, and not a complete runnable example. - -## Accessing event data - -`IOSvc` is an external Gaudi service for reading and writing EDM4hep files. The service should be imported from `k4FWCore` and named "IOSvc" as other components may look for it under this name. - -```python -from k4FWCore import IOSvc - -io_svc = IOSvc("IOSvc") # or just IOSvc() as "IOSvc" name is used by default -``` - -After instantiation the service should be register as an external service in the `ApplicationMgr`. Similarly, it's important to import the `ApplicationMgr` from `k4FWCore`: - -```python -from k4FWCore import ApplicationMgr - -ApplicationMgr( - # other args - ExtSvc=[ - io_svc, - # other services - ] -) -``` - -### Reading events - -The `IOSvc` supports reading EDM4hep ROOT files. Both files written with the ROOT TTree or RNTuple backend are supported with the backend inferred automatically from the files themselves. - -The `Input` property can be used to specify the input. The `IOSvc` will not read any files unless the `Input` property is specified. - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.Input = "input.root" -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.Input input.root -``` -::: -:::: - -:::{note} -The value assigned to the `Input` will be processed as is, in particular without regular expression or glob expansion. -::: - -A list of filenames can be given in order to specify multiple input files: - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.Input = ["input.root", "another_input.root", ] -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.Input input.root another_input.root -``` -::: -:::: - - -During processing, for each event in the Gaudi event loop the `IOSvc` will read a frame from the input and populate the Gaudi Transient Event Store (TES) with the collections stored in that frame. - -The `FirstEventEntry` property of `IOSvc` can be used to start processing from a given frame instead of from the first frame in the input: - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.FirstEventEntry = 7 # default 0 -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.FirstEventEntry 7 -``` -::: -:::: - -A list of collection names can be assigned to the `CollectionNames` property of `IOSvc` to limit the number of collections that will be populated. Without specifying the `CollectionNames` all present collections will be read and put into TES. - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.CollectionNames = ["MCParticles", "SimTrackerHits"] -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.CollectionNames "MCParticles" "SimTrackerHits" -``` -::: -:::: - -### Writing events - -The `IOSvc` supports writing EDM4hep to the ROOT output. The `Output` property can be used to specify the output. The `IOSvc` will not write any files unless the `Output` property is specified. - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.Output = "output.root" -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.Output output.root -``` -::: -:::: - -:::{note} -Unlike the `Input`, the `Output` property should be a single string even when writing multiple files is expected. When the size limit for an output file is reached, the system will automatically open a new file and start writing to it. -::: - -The writing backend can be specified with the `OutputType` property of `IOSvc`. The allowed values are `"ROOT"` for TTree-based output or `"RNTuple"` for RNTuple-based output. By default the `"ROOT"` backend is used. - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.OutputType = "RNTuple" -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.OutputType "RNTuple" -``` -::: -:::: - -During processing, at the end of each event from the Gaudi event loop the `IOSvc` will write a frame with the collections present in TES. By default all the collections will be written. The `outputCommands` property of `IOSvc` can be used to specify commands to select which collections should be written. For example, the following commands will skip writing all the collections except for the collections named `MCParticles1`, `MCParticles2` and `SimTrackerHits`: - -::::{tab-set} -:::{tab-item} Python -```python -io_svc.outputCommands = [ - "drop *", - "keep MCParticles1", - "keep MCParticles2", - "keep SimTrackerHits", -] -``` -::: -:::{tab-item} CLI -```sh -k4run --IOSvc.outputCommands \ - "drop *" \ - "keep MCParticles1" \ - "keep MCParticles2" \ - "keep SimTrackerHits" -``` -::: -:::: - -It is also possible to specify entire datatypes for keeping or dropping via the `type` sub-command, e.g. to keep everything but any collection that is of type `edm4hep::SimTrackerHitCollection` one would do: - -```python -io_svc.outputCommands = [ - "drop type edm4hep::SimTrackerHitCollection", -] -``` - -The type name here is matched against the type obtained with `podio::CollectionBase::getTypeName()`, i.e. *Collection* has to be included. Only exact matches are considered for the application of the command. - -:::{note} -The commands are processed in order so the last relevant *keep* or *drop* for any given collection will decide. -::: - - -## Accessing metadata - -The k4FWCore provides the `MetadataSvc` that allows accessing user metadata in PODIO-based data-models. There is no need to instantiate the `MetadataSvc` explicitly when using `IOSvc` as `IOSvc` can instantiate it on its own if needed. - -When both the `Input` and `Output` properties of `IOSvc` are defined, all the metadata originally present in the input will be propagated to the output, possibly adding also any user metadata created during processing. - -Unlike event data, metadata is not exposed to users through the Gaudi TES and cannot be accessed directly by algorithms in the same way. Instead, handling metadata is encapsulated within the algorithm implementation itself. For more details on how this is managed, refer to the developer documentation. - - -## Migrating from the legacy `k4DataSvc` - -Migrating from the legacy `k4DataSvc` or `PodioDataSvc` is rather straightforward. On a steering file level the `PodioDataSvc` should be replaced with the `IOSvc`, while the `PodioInput` and `PodioOutput` algorithms should be removed. For example: - -```diff --from Configurables import k4DataSvc --from Configurables import PodioInput --from Configurables import PodioOutput -+from k4FWCore import IOSvc -from k4FWCore import ApplicationMgr -from Configurables import SelectorAlg - --podioevent = k4DataSvc("EventDataSvc") --podioevent.input = "example_input.root" -+io_svc = IOSvc("IOSvc") -+io_svc.Input= "example_output.root" - --inp = PodioInput() --inp.collections = ["MCParticles", "SimTrackerHits", "TrackerHits", "Tracks"] -+io_svc.CollectionNames = ["MCParticles", "SimTrackerHits"] - -alg = SelectorAlg( - "Selector", - InputParticles="MCParticles", - InputHits="SimTrackerHits", - Output="SelectedParticles", -) - --oup = PodioOutput() --oup.filename = "example_output.root" --oup.outputCommands = ["drop MCParticles"] -+io_svc.Output = "example_output.root" -+io_svc.outputCommands = ["drop MCParticles"] - - -ApplicationMgr( -- TopAlg=[inp, alg,oup], -+ TopAlg=[alg], - EvtSel="NONE", -- ExtSvc=[podioevent], -+ ExtSvc=[io_svc], -) -``` - -Both functional algorithms and classic algorithms are compatible with either `IOSvc` or `PodioDataSvc`. From 3d84bd7e64ec93452263bfe1bf6faa30afb5c731 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Tue, 7 Apr 2026 21:38:07 +0200 Subject: [PATCH 12/16] Remove another mention in k4FWCoreTest_AlgorithmWithTFile.h --- .../src/components/k4FWCoreTest_AlgorithmWithTFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/k4FWCoreTest/src/components/k4FWCoreTest_AlgorithmWithTFile.h b/test/k4FWCoreTest/src/components/k4FWCoreTest_AlgorithmWithTFile.h index 49404ab4..455ff866 100644 --- a/test/k4FWCoreTest/src/components/k4FWCoreTest_AlgorithmWithTFile.h +++ b/test/k4FWCoreTest/src/components/k4FWCoreTest_AlgorithmWithTFile.h @@ -38,7 +38,7 @@ class SimCaloHit; /** @class k4FWCoreTest_AlgorithmWithTFile * Test producer to check that data can still be written to - * a user-declared TFile when using the PodioDataSvc + * a user-declared TFile * */ class k4FWCoreTest_AlgorithmWithTFile : public Gaudi::Algorithm { From 790800bc751ecdce6beac1af489a73a39c61066e Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Thu, 7 May 2026 22:26:14 +0200 Subject: [PATCH 13/16] Fix after rebase --- k4FWCore/include/k4FWCore/MetadataUtils.h | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/k4FWCore/include/k4FWCore/MetadataUtils.h b/k4FWCore/include/k4FWCore/MetadataUtils.h index 2e09dfe3..a671139c 100644 --- a/k4FWCore/include/k4FWCore/MetadataUtils.h +++ b/k4FWCore/include/k4FWCore/MetadataUtils.h @@ -167,27 +167,6 @@ std::optional getCellIDEncoding(const std::string& collName, const return getCollectionParameter(collName, edm4hep::labels::CellIDEncoding, comp); } -/// @brief Get a metadata parameter associated with a collection from the metadata -/// -/// Internally builds the correct parameter name from the collection name and -/// parameter name and then retrieves the value from the metadata frame via the -/// MetadataSvc -/// -/// @param collName The name of the collection for which the parameter should be -/// retrieved -/// @param paramName The name of the parameter -/// @param comp The Gaudi component (algorithm, tool) that is retrieving the -/// parameter, typically "this" -/// @tparam T The type of the parameter value -/// @tparam GaudiComp The type of the component. This will be deduced in -/// pretty much all of the use cases -/// @return The parameter value if it has been found or std::nullopt if not -template -std::optional getCollectionParameter(const std::string& collName, const std::string& paramName, - const GaudiComp* comp) { - return getParameter(podio::collMetadataParamName(collName, paramName), comp); -} - } // namespace k4FWCore #endif // FWCORE_METADATAUTILS_H From 8d3692b31c526d5490f285ed7e540038a2b5d677 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Fri, 8 May 2026 08:23:24 +0200 Subject: [PATCH 14/16] Fix tests --- test/k4FWCoreTest/options/createExampleEventData_cellID.py | 2 +- test/k4FWCoreTest/scripts/CheckOutputFiles.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/k4FWCoreTest/options/createExampleEventData_cellID.py b/test/k4FWCoreTest/options/createExampleEventData_cellID.py index 7c81754b..1186bf0e 100644 --- a/test/k4FWCoreTest/options/createExampleEventData_cellID.py +++ b/test/k4FWCoreTest/options/createExampleEventData_cellID.py @@ -45,7 +45,7 @@ consumer = k4FWCoreTest_cellID_reader() iosvc = IOSvc() -iosvc.Input = "output_k4test_exampledata_cellid.root" +iosvc.Output = "output_k4test_exampledata_cellid.root" iosvc.outputCommands = ["keep *"] ApplicationMgr( diff --git a/test/k4FWCoreTest/scripts/CheckOutputFiles.py b/test/k4FWCoreTest/scripts/CheckOutputFiles.py index b719d7ca..0372b813 100644 --- a/test/k4FWCoreTest/scripts/CheckOutputFiles.py +++ b/test/k4FWCoreTest/scripts/CheckOutputFiles.py @@ -125,10 +125,6 @@ def check_metadata(filename, expected_metadata): check_collections("functional_limited_input.root", ["MCParticles", "Links"]) check_collections("functional_limited_input_all_events.root", ["MCParticles", "Links"]) -if podio.version.build_version > podio.version.parse("1.2.0"): - check_collections("output_k4test_exampledata_limited.root", ["MCParticles", "Links"]) - check_collections("output_k4test_exampledata_limited_allevents.root", ["MCParticles", "Links"]) - mix_collections = [ # From file "VectorFloat", From bf26c77517171a2275356bfe0955892c8e4cd99b Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Fri, 8 May 2026 14:35:43 +0200 Subject: [PATCH 15/16] Check output files in CheckOutputFiles.py and remove two tests --- test/k4FWCoreTest/CMakeLists.txt | 11 +------- test/k4FWCoreTest/scripts/CheckOutputFiles.py | 9 +++++++ ...stAlgorithmWithTFile_framework_nonempty.py | 27 ------------------- ...TestAlgorithmWithTFile_myTFile_nonempty.py | 27 ------------------- 4 files changed, 10 insertions(+), 64 deletions(-) delete mode 100644 test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_framework_nonempty.py delete mode 100644 test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_myTFile_nonempty.py diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 72ad3c72..9f22acd5 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -141,16 +141,7 @@ add_test_fwcore(ReadExampleEventData options/readExampleEventData.py) set_property(TEST ReadExampleEventData APPEND PROPERTY FIXTURES_REQUIRED ExampleEventDataFile) add_test_fwcore(ReadExampleDataFromNthEvent options/readExampleDataFromNthEvent.py PROPERTIES FIXTURES_REQUIRED ExampleEventDataFile) -add_test_fwcore(AlgorithmWithTFile options/TestAlgorithmWithTFile.py PROPERTIES FIXTURES_SETUP AlgorithmWithTFileFixture) -set_property(TEST AlgorithmWithTFile PROPERTY WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) -add_test(NAME AlgorithmWithTFileCheckFrameworkOutput - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND python scripts/check_TestAlgorithmWithTFile_framework_nonempty.py) -set_property(TEST AlgorithmWithTFileCheckFrameworkOutput APPEND PROPERTY FIXTURES_REQUIRED AlgorithmWithTFileFixture) -add_test(NAME AlgorithmWithTFileCheckMyTFileOutput - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND python scripts/check_TestAlgorithmWithTFile_myTFile_nonempty.py) -set_property(TEST AlgorithmWithTFileCheckMyTFileOutput APPEND PROPERTY FIXTURES_REQUIRED AlgorithmWithTFileFixture) +add_test_fwcore(AlgorithmWithTFile options/TestAlgorithmWithTFile.py ADD_TO_CHECK_FILES) add_test_fwcore(CreateExampleEventData_cellID options/createExampleEventData_cellID.py ADD_TO_CHECK_FILES) add_test_fwcore(TwoProducers options/TwoProducers.py diff --git a/test/k4FWCoreTest/scripts/CheckOutputFiles.py b/test/k4FWCoreTest/scripts/CheckOutputFiles.py index 0372b813..be109b43 100644 --- a/test/k4FWCoreTest/scripts/CheckOutputFiles.py +++ b/test/k4FWCoreTest/scripts/CheckOutputFiles.py @@ -430,3 +430,12 @@ def check_metadata(filename, expected_metadata): "ToolFinalizeParam": 42, }, ) + +check_events("output_TestAlgorithmWithTFile_framework.root", 100) + +f_tfile = ROOT.TFile.Open("output_TestAlgorithmWithTFile_myTFile.root") +mytree = f_tfile.Get("mytree") +if mytree is None: + raise RuntimeError("output_TestAlgorithmWithTFile_myTFile.root has no TTree named mytree") +if mytree.GetEntries() == 0: + raise RuntimeError("output_TestAlgorithmWithTFile_myTFile.root contains TTree mytree with no entries") diff --git a/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_framework_nonempty.py b/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_framework_nonempty.py deleted file mode 100644 index 0aa70dfb..00000000 --- a/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_framework_nonempty.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# 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. -# -import ROOT - -f = ROOT.TFile.Open("output_TestAlgorithmWithTFile_framework.root") -t = f.Get("events") -print( - "File: output_TestAlgorithmWithTFile_framework.root contains TTree events with " - + str(t.GetEntries()) - + " entries." -) diff --git a/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_myTFile_nonempty.py b/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_myTFile_nonempty.py deleted file mode 100644 index 82b99033..00000000 --- a/test/k4FWCoreTest/scripts/check_TestAlgorithmWithTFile_myTFile_nonempty.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# 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. -# -import ROOT - -f = ROOT.TFile.Open("output_TestAlgorithmWithTFile_myTFile.root") -t = f.Get("mytree") -print( - "File: output_TestAlgorithmWithTFile_myTFile.root contains TTree mytree with " - + str(t.GetEntries()) - + " entries." -) From afeea0488de68857a7b55fc580811c5b2524df6b Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Fri, 8 May 2026 22:19:41 +0200 Subject: [PATCH 16/16] Fix pre-commit --- test/k4FWCoreTest/scripts/CheckOutputFiles.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/k4FWCoreTest/scripts/CheckOutputFiles.py b/test/k4FWCoreTest/scripts/CheckOutputFiles.py index be109b43..a2466416 100644 --- a/test/k4FWCoreTest/scripts/CheckOutputFiles.py +++ b/test/k4FWCoreTest/scripts/CheckOutputFiles.py @@ -438,4 +438,6 @@ def check_metadata(filename, expected_metadata): if mytree is None: raise RuntimeError("output_TestAlgorithmWithTFile_myTFile.root has no TTree named mytree") if mytree.GetEntries() == 0: - raise RuntimeError("output_TestAlgorithmWithTFile_myTFile.root contains TTree mytree with no entries") + raise RuntimeError( + "output_TestAlgorithmWithTFile_myTFile.root contains TTree mytree with no entries" + )