diff --git a/k4MarlinWrapper/examples/clicRec_e4h_input.py b/k4MarlinWrapper/examples/clicRec_e4h_input.py index ee802f4e..9d8021fa 100644 --- a/k4MarlinWrapper/examples/clicRec_e4h_input.py +++ b/k4MarlinWrapper/examples/clicRec_e4h_input.py @@ -19,10 +19,16 @@ import os -from Gaudi.Configuration import * +from Gaudi.Configuration import DEBUG, WARNING -from Configurables import LcioEvent, MarlinProcessorWrapper -from k4MarlinWrapper.parseConstants import * +from Configurables import MarlinProcessorWrapper +from k4MarlinWrapper.parseConstants import parseConstants + +from Configurables import Lcio2EDM4hepTool, EDM4hep2LcioTool +from Configurables import k4DataSvc, PodioInput, PodioOutput, EventDataSvc + +from k4FWCore import ApplicationMgr, IOSvc +from k4FWCore.parseArgs import parser algList = [] @@ -33,22 +39,33 @@ parseConstants(CONSTANTS) - -# For converters -from Configurables import ToolSvc, Lcio2EDM4hepTool, EDM4hep2LcioTool - - -from Configurables import k4DataSvc, PodioInput - -evtsvc = k4DataSvc("EventDataSvc") -evtsvc.input = os.path.join( - "$TEST_DIR/inputFiles/", os.environ.get("INPUTFILE", "ttbar_edm4hep_frame.root") +parser.add_argument( + "--iosvc", action="store_true", default=False, help="Use IOSvc instead of PodioDataSvc" ) - - -inp = PodioInput("InputReader") -inp.OutputLevel = DEBUG - +parser.add_argument("--rec-output", help="Output file name for the REC file") +parser.add_argument("--dst-output", help="Output file name for the DST file") + +args = parser.parse_known_args()[0] + +if args.iosvc: + evtsvc = EventDataSvc("EventDataSvc") + iosvc = IOSvc() + iosvc.Input = os.path.join( + "$TEST_DIR/inputFiles/", os.environ.get("INPUTFILE", "ttbar_edm4hep_frame.root") + ) + iosvc.Output = "my_output.root" + iosvc.outputDstName = ["keep *, drop RefinedVertexJets_PID_RefinedVertex"] +else: + evtsvc = k4DataSvc("EventDataSvc") + evtsvc.input = os.path.join( + "$TEST_DIR/inputFiles/", os.environ.get("INPUTFILE", "ttbar_edm4hep_frame.root") + ) + + inp = PodioInput("InputReader") + inp.OutputLevel = DEBUG + + out = PodioOutput("PodioOutput", filename="my_output.root") + out.outputCommands = ["keep *, drop RefinedVertexJets_PID_RefinedVertex"] MyAIDAProcessor = MarlinProcessorWrapper("MyAIDAProcessor") MyAIDAProcessor.OutputLevel = WARNING @@ -1167,7 +1184,7 @@ "DropCollectionTypes": [], "FullSubsetCollections": ["EfficientMCParticles", "InefficientMCParticles"], "KeepCollectionNames": [], - "LCIOOutputFile": ["Output_REC_e4h_input.slcio"], + "LCIOOutputFile": [args.rec_output], "LCIOWriteMode": ["WRITE_NEW"], } @@ -1233,7 +1250,7 @@ "RefinedVertices", "RefinedVertices_RP", ], - "LCIOOutputFile": ["Output_DST_e4h_input.slcio"], + "LCIOOutputFile": [args.dst_output], "LCIOWriteMode": ["WRITE_NEW"], } @@ -2429,6 +2446,7 @@ } +<<<<<<< HEAD # Write output to EDM4hep from Configurables import PodioOutput @@ -2437,6 +2455,8 @@ algList.append(inp) +======= +>>>>>>> cb3c7a3 (Add support for running with IOSvc) algList.append(MyAIDAProcessor) algList.append(EventNumber) algList.append(InitDD4hep) @@ -2486,8 +2506,8 @@ # # algList.append(VertexFinderUnconstrained) # Config.VertexUnconstrainedON algList.append(Output_REC) algList.append(Output_DST) -algList.append(out) -from Configurables import ApplicationMgr +if not args.iosvc: + algList = [inp] + algList + [out] ApplicationMgr(TopAlg=algList, EvtSel="NONE", EvtMax=3, ExtSvc=[evtsvc], OutputLevel=WARNING) diff --git a/k4MarlinWrapper/k4MarlinWrapper/converters/EDM4hep2Lcio.h b/k4MarlinWrapper/k4MarlinWrapper/converters/EDM4hep2Lcio.h index 4d281004..c0d7658a 100644 --- a/k4MarlinWrapper/k4MarlinWrapper/converters/EDM4hep2Lcio.h +++ b/k4MarlinWrapper/k4MarlinWrapper/converters/EDM4hep2Lcio.h @@ -64,6 +64,8 @@ class EDM4hep2LcioTool : public AlgTool, virtual public IEDMConverter { PodioDataSvc* m_podioDataSvc; ServiceHandle m_eventDataSvc; + std::vector m_collectionNames; + std::map m_idToName; void convertTracks(TrackMap& tracks_vec, const std::string& e4h_coll_name, const std::string& lcio_coll_name, lcio::LCEventImpl* lcio_event); @@ -110,6 +112,8 @@ class EDM4hep2LcioTool : public AlgTool, virtual public IEDMConverter { std::vector& pidCollections, std::vector& dQdxCollections); + StatusCode getAvailableCollectionsFromStore(); + /// Get an EDM4hep collection by name, consulting either the podio based data /// svc or the IOSvc podio::CollectionBase* getEDM4hepCollection(const std::string& name) const; diff --git a/k4MarlinWrapper/k4MarlinWrapper/converters/Lcio2EDM4hep.h b/k4MarlinWrapper/k4MarlinWrapper/converters/Lcio2EDM4hep.h index a72a11f3..79d825d5 100644 --- a/k4MarlinWrapper/k4MarlinWrapper/converters/Lcio2EDM4hep.h +++ b/k4MarlinWrapper/k4MarlinWrapper/converters/Lcio2EDM4hep.h @@ -58,7 +58,7 @@ class Lcio2EDM4hepTool : public AlgTool, virtual public IEDMConverter { Gaudi::Property> m_collNames{this, "collNameMapping", {}}; Gaudi::Property m_convertAll{this, "convertAll", true}; - ServiceHandle m_eds; + ServiceHandle m_eventDataSvc; PodioDataSvc* m_podioDataSvc; // ********************************** diff --git a/k4MarlinWrapper/src/components/EDM4hep2Lcio.cpp b/k4MarlinWrapper/src/components/EDM4hep2Lcio.cpp index 30b81a25..cf5249c1 100644 --- a/k4MarlinWrapper/src/components/EDM4hep2Lcio.cpp +++ b/k4MarlinWrapper/src/components/EDM4hep2Lcio.cpp @@ -17,16 +17,24 @@ * limitations under the License. */ #include "k4MarlinWrapper/converters/EDM4hep2Lcio.h" +#include #include "GlobalConvertedObjectsMap.h" +#include "UTIL/PIDHandler.h" + #include "edm4hep/Constants.h" #include "k4FWCore/DataHandle.h" +#include "k4FWCore/FunctionalUtils.h" #include "k4FWCore/MetaDataHandle.h" #include "k4FWCore/PodioDataSvc.h" #include "GaudiKernel/AnyDataWrapper.h" +#include "GaudiKernel/IDataManagerSvc.h" +#include "GaudiKernel/IDataProviderSvc.h" +#include "GaudiKernel/SmartDataPtr.h" +#include #include DECLARE_COMPONENT(EDM4hep2LcioTool); @@ -55,14 +63,14 @@ EDM4hep2LcioTool::EDM4hep2LcioTool(const std::string& type, const std::string& n } StatusCode EDM4hep2LcioTool::initialize() { - StatusCode sc = m_eventDataSvc.retrieve(); - m_podioDataSvc = dynamic_cast(m_eventDataSvc.get()); - + StatusCode sc = m_eventDataSvc.retrieve(); if (sc == StatusCode::FAILURE) { - error() << "Error retrieving Event Data Service" << endmsg; + error() << "Could not retrieve the EventDataSvc;" << endmsg; return StatusCode::FAILURE; } + m_podioDataSvc = dynamic_cast(m_eventDataSvc.get()); + return AlgTool::initialize(); } @@ -277,7 +285,7 @@ void EDM4hep2LcioTool::convertEventHeader(const std::string& e4h_coll_name, lcio podio::CollectionBase* EDM4hep2LcioTool::getEDM4hepCollection(const std::string& collName) const { DataObject* p; - auto sc = m_podioDataSvc->retrieveObject(collName, p); + auto sc = m_eventDataSvc->retrieveObject(collName, p); if (sc.isFailure()) { throw GaudiException("Collection not found", name(), StatusCode::FAILURE); } @@ -302,14 +310,59 @@ podio::CollectionBase* EDM4hep2LcioTool::getEDM4hepCollection(const std::string& throw GaudiException("Collection could not be casted to the expected type", name(), StatusCode::FAILURE); } +StatusCode EDM4hep2LcioTool::getAvailableCollectionsFromStore() { + SmartIF mgr; + mgr = evtSvc(); + + SmartDataPtr root(evtSvc(), "/Event"); + if (!root) { + error() << "Failed to retrieve root object /Event" << endmsg; + return StatusCode::FAILURE; + } + + auto pObj = root->registry(); + if (!pObj) { + error() << "Failed to retrieve the root registry object" << endmsg; + return StatusCode::FAILURE; + } + std::vector leaves; + StatusCode sc = mgr->objectLeaves(pObj, leaves); + if (!sc.isSuccess()) { + error() << "Failed to retrieve object leaves" << endmsg; + return StatusCode::FAILURE; + } + for (const auto& pReg : leaves) { + if (pReg->name() == k4FWCore::frameLocation) { + continue; + } + DataObject* p; + sc = m_eventDataSvc->retrieveObject("/Event" + pReg->name(), p); + if (sc.isFailure()) { + error() << "Could not retrieve object " << pReg->name() << " from the EventStore" << endmsg; + return sc; + } + auto wrapper = dynamic_cast>*>(p); + if (!wrapper) { + continue; + } + // Remove the leading / + m_collectionNames.push_back(pReg->name().substr(1, pReg->name().size() - 1)); + m_idToName.emplace(wrapper->getData()->getID(), pReg->name()); + } + return StatusCode::SUCCESS; +} + // Select the appropriate method to convert a collection given its type void EDM4hep2LcioTool::convertAdd(const std::string& e4h_coll_name, const std::string& lcio_coll_name, lcio::LCEventImpl* lcio_event, CollectionPairMappings& collection_pairs, std::vector& pidCollections, std::vector& dQdxCollections) { - const auto& metadata = m_podioDataSvc->getMetaDataFrame(); - const auto collPtr = getEDM4hepCollection(e4h_coll_name); - const auto fulltype = collPtr->getValueTypeName(); + std::optional> metadata; + if (m_podioDataSvc) { + metadata = m_podioDataSvc->getMetaDataFrame(); + } + const auto collPtr = getEDM4hepCollection(e4h_coll_name); + const auto fulltype = collPtr->getValueTypeName(); debug() << "Converting type " << fulltype << " from input " << e4h_coll_name << endmsg; @@ -340,8 +393,32 @@ void EDM4hep2LcioTool::convertAdd(const std::string& e4h_coll_name, const std::s } else if (fulltype == "edm4hep::EventHeader") { convertEventHeader(e4h_coll_name, lcio_event); } else if (fulltype == "edm4hep::ParticleID") { - pidCollections.emplace_back(e4h_coll_name, static_cast(collPtr), - edm4hep::utils::PIDHandler::getAlgoInfo(metadata, e4h_coll_name)); + std::optional maybeAlgoName; + std::optional maybeAlgoType; + std::optional> maybeParamNames; + + if (m_podioDataSvc) { + const auto& frame = metadata.value().get(); + maybeAlgoName = + frame.getParameter(podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDAlgoName)); + maybeAlgoType = + frame.getParameter(podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDAlgoType)); + maybeParamNames = frame.getParameter>( + podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDParameterNames)); + + } else { + maybeAlgoName = k4FWCore::getParameter( + podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDAlgoName)); + maybeAlgoType = + k4FWCore::getParameter(podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDAlgoType)); + maybeParamNames = k4FWCore::getParameter>( + podio::collMetadataParamName(e4h_coll_name, edm4hep::labels::PIDParameterNames)); + } + + edm4hep::utils::ParticleIDMeta pidInfo{std::move(maybeAlgoName.value()), maybeAlgoType.value(), + maybeParamNames.value()}; + + pidCollections.emplace_back(e4h_coll_name, static_cast(collPtr), pidInfo); } else if (fulltype == "edm4hep::RecDqDx") { dQdxCollections.emplace_back(e4h_coll_name, static_cast(collPtr)); } @@ -362,8 +439,17 @@ void EDM4hep2LcioTool::convertAdd(const std::string& e4h_coll_name, const std::s // Parse property parameters and convert the indicated collections. // Use the collection names in the parameters to read and write them StatusCode EDM4hep2LcioTool::convertCollections(lcio::LCEventImpl* lcio_event) { - const auto& edmEvent = m_podioDataSvc->getEventFrame(); - const auto collections = edmEvent.getAvailableCollections(); + std::optional> edmEvent; + if (m_collectionNames.empty() && m_podioDataSvc) { + edmEvent = m_podioDataSvc->getEventFrame(); + m_collectionNames = edmEvent.value().get().getAvailableCollections(); + } else if (m_collectionNames.empty()) { + auto sc = getAvailableCollectionsFromStore(); + if (sc.isFailure()) { + warning() << "Could not retrieve available collections from the EventStore" << endmsg; + return sc; + } + } // Start off with the pre-defined collection name mappings auto collsToConvert{m_collNames.value()}; // We *always* want to convert the EventHeader @@ -372,7 +458,7 @@ StatusCode EDM4hep2LcioTool::convertCollections(lcio::LCEventImpl* lcio_event) { info() << "Converting all collections from EDM4hep to LCIO" << endmsg; // And simply add the rest, exploiting the fact that emplace will not // replace existing entries with the same key - for (const auto& name : collections) { + for (const auto& name : m_collectionNames) { collsToConvert.emplace(name, name); } } @@ -399,13 +485,39 @@ StatusCode EDM4hep2LcioTool::convertCollections(lcio::LCEventImpl* lcio_event) { } debug() << "Event: " << lcio_event->getEventNumber() << " Run: " << lcio_event->getRunNumber() << endmsg; - // Deal with EDM4hep2LCIOConv::sortParticleIDs(pidCollections); + if (!m_podioDataSvc) { + DataObject* p; + StatusCode code = m_eventDataSvc->retrieveObject("/Event" + k4FWCore::frameLocation, p); + if (code.isSuccess()) { + auto* frame = dynamic_cast*>(p); + edmEvent = std::cref(frame->getData()); + } else { + auto frame = podio::Frame{}; + edmEvent = frame; + } + } for (const auto& pidCollMeta : pidCollections) { - const auto algoId = attachParticleIDMetaData(lcio_event, edmEvent, pidCollMeta); + auto algoId = attachParticleIDMetaData(lcio_event, edmEvent.value(), pidCollMeta); if (!algoId.has_value()) { - warning() << "Could not determine algorithm type for ParticleID collection " << pidCollMeta.name - << " for setting consistent metadata" << endmsg; + // Now go over the collections that have been produced in a functional algorithm (if any) + bool found = false; + if (!m_podioDataSvc) { + const auto id = (*pidCollMeta.coll)[0].getParticle().id().collectionID; + if (auto it = m_idToName.find(id); it != m_idToName.end()) { + auto name = it->second; + if (pidCollMeta.metadata.has_value()) { + UTIL::PIDHandler pidHandler(lcio_event->getCollection(name)); + algoId = + pidHandler.addAlgorithm(pidCollMeta.metadata.value().algoName, pidCollMeta.metadata.value().paramNames); + found = true; + } + } + } + if (!found) { + warning() << "Could not determine algorithm type for ParticleID collection " << pidCollMeta.name + << " for setting consistent metadata" << endmsg; + } } convertParticleIDs(collection_pairs.particleIDs, pidCollMeta.name, algoId.value_or(-1)); } diff --git a/k4MarlinWrapper/src/components/Lcio2EDM4hep.cpp b/k4MarlinWrapper/src/components/Lcio2EDM4hep.cpp index 19bc2462..b57c80de 100644 --- a/k4MarlinWrapper/src/components/Lcio2EDM4hep.cpp +++ b/k4MarlinWrapper/src/components/Lcio2EDM4hep.cpp @@ -32,6 +32,7 @@ #include "GaudiKernel/AnyDataWrapper.h" +#include #include DECLARE_COMPONENT(Lcio2EDM4hepTool); @@ -39,19 +40,17 @@ DECLARE_COMPONENT(Lcio2EDM4hepTool); using namespace k4MarlinWrapper; Lcio2EDM4hepTool::Lcio2EDM4hepTool(const std::string& type, const std::string& name, const IInterface* parent) - : AlgTool(type, name, parent), m_eds("EventDataSvc", "Lcio2EDM4hepTool") { + : AlgTool(type, name, parent), m_eventDataSvc("EventDataSvc", "Lcio2EDM4hepTool") { declareInterface(this); - StatusCode sc = m_eds.retrieve(); + StatusCode sc = m_eventDataSvc.retrieve(); if (sc.isFailure()) { error() << "Could not retrieve EventDataSvc" << endmsg; } } StatusCode Lcio2EDM4hepTool::initialize() { - m_podioDataSvc = dynamic_cast(m_eds.get()); - if (!m_podioDataSvc) - return StatusCode::FAILURE; + m_podioDataSvc = dynamic_cast(m_eventDataSvc.get()); return AlgTool::initialize(); } @@ -62,9 +61,13 @@ StatusCode Lcio2EDM4hepTool::finalize() { return AlgTool::finalize(); } // Check if a collection was already registered to skip it // ********************************** bool Lcio2EDM4hepTool::collectionExist(const std::string& collection_name) { - auto collections = m_podioDataSvc->getEventFrame().getAvailableCollections(); + std::vector collections; + //TODO: + if (m_podioDataSvc) { + collections = m_podioDataSvc->getEventFrame().getAvailableCollections(); + } for (const auto& name : collections) { - if (collection_name == name) { + if (name == collection_name) { debug() << "Collection named " << name << " already registered, skipping conversion." << endmsg; return true; } @@ -85,7 +88,7 @@ void Lcio2EDM4hepTool::registerCollection( // No need to check for pre-existing collections, since we only ever end up // here if that is not the case - auto sc = m_podioDataSvc->registerObject("/Event", "/" + std::string(name), wrapper); + auto sc = m_eventDataSvc->registerObject("/Event", "/" + std::string(name), wrapper); if (sc == StatusCode::FAILURE) { error() << "Could not register collection " << name << endmsg; } @@ -98,8 +101,14 @@ void Lcio2EDM4hepTool::registerCollection( for (auto& elem : string_keys) { if (elem == edm4hep::labels::CellIDEncoding) { const auto& lcio_coll_cellid_str = lcioColl->getParameters().getStringVal(lcio::LCIO::CellIDEncoding); - auto& mdFrame = m_podioDataSvc->getMetaDataFrame(); - mdFrame.putParameter(podio::collMetadataParamName(name, edm4hep::labels::CellIDEncoding), lcio_coll_cellid_str); + if (m_podioDataSvc) { + auto& mdFrame = m_podioDataSvc->getMetaDataFrame(); + mdFrame.putParameter(podio::collMetadataParamName(name, edm4hep::labels::CellIDEncoding), + lcio_coll_cellid_str); + } else { + k4FWCore::putParameter(podio::collMetadataParamName(name, edm4hep::labels::CellIDEncoding), + lcio_coll_cellid_str); + } debug() << "Storing CellIDEncoding " << podio::collMetadataParamName(name, edm4hep::labels::CellIDEncoding) << " value: " << lcio_coll_cellid_str << endmsg; } else { @@ -131,8 +140,10 @@ namespace { StatusCode Lcio2EDM4hepTool::convertCollections(lcio::LCEventImpl* the_event) { // Convert event parameters - // auto& frame = const_cast(m_podioDataSvc->getEventFrame()); - auto& frame = m_podioDataSvc->m_eventframe; + std::optional> frame; + if (m_podioDataSvc) { + frame = m_podioDataSvc->m_eventframe; + } LCIO2EDM4hepConv::convertObjectParameters(the_event, frame); // Convert Event Header outside the collections loop @@ -208,9 +219,19 @@ StatusCode Lcio2EDM4hepTool::convertCollections(lcio::LCEventImpl* the_event) { } // Set the ParticleID meta information - auto& metadataFrame = m_podioDataSvc->getMetaDataFrame(); - for (const auto& [collName, pidInfo] : pidInfos) { - edm4hep::utils::PIDHandler::setAlgoInfo(metadataFrame, collName, pidInfo); + // TODO: Clean up + if (m_podioDataSvc) { + auto& metadataFrame = m_podioDataSvc->getMetaDataFrame(); + for (const auto& [collName, pidInfo] : pidInfos) { + edm4hep::utils::PIDHandler::setAlgoInfo(metadataFrame, collName, pidInfo); + } + } else { + for (const auto& [collName, pidInfo] : pidInfos) { + k4FWCore::putParameter(podio::collMetadataParamName(collName, edm4hep::labels::PIDAlgoName), pidInfo.algoName); + k4FWCore::putParameter(podio::collMetadataParamName(collName, edm4hep::labels::PIDAlgoType), pidInfo.algoType()); + k4FWCore::putParameter(podio::collMetadataParamName(collName, edm4hep::labels::PIDParameterNames), + pidInfo.paramNames); + } } // We want one "global" map that is created the first time it is used in the event. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 358357f2..5ca42b8a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -77,7 +77,8 @@ set_tests_properties ( same_num_io PASS_REGULAR_EXPRESSION "Input and output have same number of events") # Test clicReconstruction with EDM4hep input and output -ExternalData_Add_Test( marlinwrapper_tests NAME clicRec_edm4hep_input COMMAND bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/clicRec_e4h_input.sh DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root}") +ExternalData_Add_Test( marlinwrapper_tests NAME clicRec_edm4hep_input COMMAND bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/clicRec_e4h_input.sh DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root} --no-iosvc") +ExternalData_Add_Test( marlinwrapper_tests NAME clicRec_edm4hep_input_iosvc COMMAND bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/clicRec_e4h_input.sh DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root} --iosvc") # Run clicReconstruction sequence with LCIO input and output, no converters, with inter-event parallelism ExternalData_Add_Test( marlinwrapper_tests NAME clicRec_lcio_mt COMMAND bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/clicRec_lcio_mt.sh DATA{${PROJECT_SOURCE_DIR}/test/input_files/testSimulation.slcio}") @@ -88,11 +89,16 @@ add_test( clic_geo_test ${K4RUN} ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/geoTest_ # Test for checking whether the converters can resolve relations across # multiple processors ExternalData_Add_Test( marlinwrapper_tests NAME global_converter_maps COMMAND ${K4RUN} ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/test_global_converter_maps.py --EventDataSvc.input DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root}) +ExternalData_Add_Test( marlinwrapper_tests NAME global_converter_maps_iosvc COMMAND ${K4RUN} ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/test_global_converter_maps.py --iosvc --IOSvc.Input DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root}) ExternalData_Add_Test( marlinwrapper_tests NAME link_conversion_edm4hep_to_lcio COMMAND ${K4RUN} ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/test_link_conversion_edm4hep.py --inputfile DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root} ) +ExternalData_Add_Test( marlinwrapper_tests + NAME link_conversion_edm4hep_to_lcio_iosvc + COMMAND ${K4RUN} ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/test_link_conversion_edm4hep.py --iosvc --inputfile DATA{${PROJECT_SOURCE_DIR}/test/input_files/ttbar_20240223_edm4hep.root} +) add_test( event_header_conversion bash -c "k4run ${CMAKE_CURRENT_SOURCE_DIR}/gaudi_opts/createEventHeader.py && anajob test.slcio | grep 'EVENT: 42'" ) @@ -104,7 +110,7 @@ set_tests_properties(${test_names} PROPERTIES ENVIRONMENT ) set_tests_properties( - clicRec clicRec_lcio_mt clicRec_edm4hep_input + clicRec clicRec_lcio_mt clicRec_edm4hep_input clicRec_edm4hep_input_iosvc PROPERTIES DEPENDS CLICPerformance_setup ) diff --git a/test/gaudi_opts/test_global_converter_maps.py b/test/gaudi_opts/test_global_converter_maps.py index 2746c3f8..846734d0 100644 --- a/test/gaudi_opts/test_global_converter_maps.py +++ b/test/gaudi_opts/test_global_converter_maps.py @@ -23,20 +23,40 @@ from Configurables import ( PodioInput, + PodioOutput, MarlinProcessorWrapper, k4DataSvc, Lcio2EDM4hepTool, EDM4hep2LcioTool, MCRecoLinkChecker, - ApplicationMgr, PseudoRecoAlgorithm, + EventDataSvc, ) -evtsvc = k4DataSvc("EventDataSvc") +from k4FWCore import ApplicationMgr, IOSvc -podioInput = PodioInput("InputReader") -podioInput.collections = ["MCParticles"] -podioInput.OutputLevel = INFO +from k4FWCore.parseArgs import parser + +parser.add_argument( + "--iosvc", action="store_true", default=False, help="Use IOSvc instead of PodioDataSvc" +) + +args = parser.parse_known_args()[0] + +if args.iosvc: + evtsvc = EventDataSvc("EventDataSvc") +else: + evtsvc = k4DataSvc("EventDataSvc") + +if args.iosvc: + iosvc = IOSvc() + iosvc.Output = "global_converter_maps_iosvc.root" +else: + podioInput = PodioInput("InputReader") + podioInput.collections = ["MCParticles"] + podioInput.OutputLevel = INFO + podioOutput = PodioOutput("OutputWriter") + podioOutput.filename = "global_converter_maps.root" PseudoRecoAlg = PseudoRecoAlgorithm( "PseudoRecoAlgorithm", InputMCs=["MCParticles"], OutputRecos=["PseudoRecoParticles"] @@ -74,10 +94,12 @@ mcLinkChecker.OutputLevel = DEBUG algList = [ - podioInput, PseudoRecoAlg, TrivialMCTruthLinkerProc, mcLinkChecker, ] -ApplicationMgr(TopAlg=algList, EvtSel="NONE", EvtMax=3, ExtSvc=[evtsvc], OutputLevel=DEBUG) +if not args.iosvc: + algList = [podioInput] + algList + [podioOutput] + +ApplicationMgr(TopAlg=algList, EvtSel="NONE", EvtMax=1, ExtSvc=[evtsvc], OutputLevel=DEBUG) diff --git a/test/gaudi_opts/test_link_conversion_edm4hep.py b/test/gaudi_opts/test_link_conversion_edm4hep.py index 92080f7e..26c22cef 100644 --- a/test/gaudi_opts/test_link_conversion_edm4hep.py +++ b/test/gaudi_opts/test_link_conversion_edm4hep.py @@ -23,24 +23,33 @@ from Configurables import ( PodioInput, k4DataSvc, - ApplicationMgr, PseudoRecoAlgorithm, TrivialMCRecoLinker, MarlinProcessorWrapper, EDM4hep2LcioTool, + EventDataSvc, ) +from k4FWCore import ApplicationMgr, IOSvc + from k4FWCore.parseArgs import parser parser.add_argument("--inputfile", help="Input file") -my_args = parser.parse_known_args()[0] - -evtsvc = k4DataSvc("EventDataSvc") -evtsvc.input = my_args.inputfile +parser.add_argument( + "--iosvc", action="store_true", default=False, help="Use IOSvc instead of PodioDataSvc" +) +args = parser.parse_known_args()[0] -podioInput = PodioInput("InputReader") -podioInput.collections = ["MCParticles"] -podioInput.OutputLevel = INFO +if args.iosvc: + evtsvc = EventDataSvc("EventDataSvc") + iosvc = IOSvc() + iosvc.Input = args.inputfile +else: + evtsvc = k4DataSvc("EventDataSvc") + evtsvc.input = args.inputfile + podioInput = PodioInput("InputReader") + podioInput.collections = ["MCParticles"] + podioInput.OutputLevel = INFO PseudoRecoAlg = PseudoRecoAlgorithm( @@ -74,9 +83,13 @@ mcLinkConverter.OutputLevel = DEBUG MarlinMCLinkChecker.EDM4hep2LcioTool = mcLinkConverter +algList = [PseudoRecoAlg, MCRecoLinker, MarlinMCLinkChecker] + +if not args.iosvc: + algList = [podioInput] + algList ApplicationMgr( - TopAlg=[podioInput, PseudoRecoAlg, MCRecoLinker, MarlinMCLinkChecker], + TopAlg=algList, ExtSvc=[evtsvc], EvtMax=-1, EvtSel="NONE", diff --git a/test/scripts/clicRec_e4h_input.sh b/test/scripts/clicRec_e4h_input.sh index 7b67072a..5c9d6916 100755 --- a/test/scripts/clicRec_e4h_input.sh +++ b/test/scripts/clicRec_e4h_input.sh @@ -23,7 +23,19 @@ set -eu cd CLICPerformance/clicConfig -k4run $EXAMPLE_DIR/clicRec_e4h_input.py --EventDataSvc.input=$1 +if [ "$2" = "--iosvc" ]; then + iosvc="_iosvc" + echo "Running with IO service" + file_arg="--iosvc --IOSvc.Input=$1" +elif [ "$2" = "--no-iosvc" ]; then + iosvc="" + echo "Running without IO service" + file_arg="--EventDataSvc.input=$1" +else + echo "Wrong argument $2" + return 1 +fi +k4run $EXAMPLE_DIR/clicRec_e4h_input.py ${file_arg} --rec-output Output_REC_e4h_input$iosvc.slcio --dst-output Output_DST_e4h_input$iosvc.slcio input_num_events=$(python $TEST_DIR/python/root_num_events.py $1) output_num_events=$(python $TEST_DIR/python/root_num_events.py my_output.root) @@ -35,14 +47,15 @@ if [ "$input_num_events" != "$output_num_events" ]; then fi # Second check: contents (at least superficially) -echo "Comparing contents of Output_REC_e4h_input.slcio" -if ! diff <(anajob Output_REC_e4h_input.slcio) $TEST_DIR/inputFiles/anajob_Output_REC.expected; then +# Exclude the file name since it is different when using the IOSvc +echo "Comparing contents of Output_REC_e4h_input$iosvc.slcio" +if ! diff -I "Output_REC_e4h_input.*\.slcio" <(anajob Output_REC_e4h_input$iosvc.slcio) $TEST_DIR/inputFiles/anajob_Output_REC.expected; then echo "File contents of REC slcio file are not as expected" exit 1 fi -echo "Comparing contents of Output_DST_e4h_input.slcio" -if ! diff <(anajob Output_DST_e4h_input.slcio) $TEST_DIR/inputFiles/anajob_Output_DST.expected; then +echo "Comparing contents of Output_DST_e4h_input$iosvc.slcio" +if ! diff -I "Output_DST_e4h_input.*\.slcio" <(anajob Output_DST_e4h_input$iosvc.slcio) $TEST_DIR/inputFiles/anajob_Output_DST.expected; then echo "File contents of DST slcio file are not as expected" exit 1 fi