diff --git a/k4FWCore/components/IOSvc.cpp b/k4FWCore/components/IOSvc.cpp index f48c501d..c2c6869b 100644 --- a/k4FWCore/components/IOSvc.cpp +++ b/k4FWCore/components/IOSvc.cpp @@ -61,10 +61,16 @@ StatusCode IOSvc::initialize() { m_entries = m_reader->getEntries(podio::Category::Event); } + if ((m_entries && m_firstEventEntry >= m_entries) || m_firstEventEntry < 0) { + error() << "First event entry is larger than the number of entries in the file or negative" << endmsg; + return StatusCode::FAILURE; + } + if (!m_writingFileNameDeprecated.empty()) { warning() << ".output is deprecated, use .Output instead in the steering file" << endmsg; m_writingFileName = m_writingFileNameDeprecated; } + m_nextEntry = m_firstEventEntry; m_switch = KeepDropSwitch(m_outputCommands); diff --git a/k4FWCore/components/IOSvc.h b/k4FWCore/components/IOSvc.h index 4a986dfe..954b08e6 100644 --- a/k4FWCore/components/IOSvc.h +++ b/k4FWCore/components/IOSvc.h @@ -67,6 +67,7 @@ class IOSvc : public extends { Gaudi::Property m_importedFromk4FWCore{ this, "ImportedFromk4FWCore", false, "This is set to true when IOSvc is imported from k4FWCore instead of Configurables in python"}; + Gaudi::Property m_firstEventEntry{this, "FirstEventEntry", 0, "First event entry to read"}; std::mutex m_changeBufferLock; diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index e65fc048..972fafcc 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -141,9 +141,10 @@ add_test_with_env(createEventHeaderConcurrent options/createEventHeaderConcurren add_test_with_env(FunctionalWrongImport options/ExampleFunctionalWrongImport.py) set_tests_properties(FunctionalWrongImport PROPERTIES PASS_REGULAR_EXPRESSION "ImportError: Importing ApplicationMgr or IOSvc from Configurables is not allowed.") +add_test_with_env(FunctionalReadNthEvent options/ExampleFunctionalReadNthEvent.py) add_test(NAME FunctionalCheckFiles COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/options/CheckOutputFiles.py) -set_tests_properties(FunctionalCheckFiles PROPERTIES DEPENDS "FunctionalFile;FunctionalMTFile;FunctionalMultipleFile;FunctionalOutputCommands;FunctionalProducerAbsolutePath;FunctionalTransformerRuntimeEmpty;FunctionalMix;FunctionalMixIOSvc;FunctionalTransformerHist;FunctionalCollectionMerger;FunctionalFilterFile;FunctionalMetadata;FunctionalMetadataOldAlgorithm;createEventHeaderConcurrent") +set_tests_properties(FunctionalCheckFiles PROPERTIES DEPENDS "FunctionalFile;FunctionalMTFile;FunctionalMultipleFile;FunctionalOutputCommands;FunctionalProducerAbsolutePath;FunctionalTransformerRuntimeEmpty;FunctionalMix;FunctionalMixIOSvc;FunctionalTransformerHist;FunctionalCollectionMerger;FunctionalFilterFile;FunctionalMetadata;FunctionalMetadataOldAlgorithm;createEventHeaderConcurrent;FunctionalReadNthEvent") # Do this after checking the files not to overwrite them add_test_with_env(FunctionalFile_toolong options/ExampleFunctionalFile.py -n 999 PROPERTIES DEPENDS FunctionalCheckFiles PASS_REGULAR_EXPRESSION diff --git a/test/k4FWCoreTest/options/CheckOutputFiles.py b/test/k4FWCoreTest/options/CheckOutputFiles.py index 90c8971d..45b3b0a0 100644 --- a/test/k4FWCoreTest/options/CheckOutputFiles.py +++ b/test/k4FWCoreTest/options/CheckOutputFiles.py @@ -209,3 +209,8 @@ def check_events(filename, number): if event_number in seen_event_numbers: raise RuntimeError(f"Event number {event_number} is duplicated") seen_event_numbers.add(event_number) + +check_events( + "functional_nth_event.root", + 3, +) diff --git a/test/k4FWCoreTest/options/ExampleFunctionalReadNthEvent.py b/test/k4FWCoreTest/options/ExampleFunctionalReadNthEvent.py new file mode 100644 index 00000000..766d1410 --- /dev/null +++ b/test/k4FWCoreTest/options/ExampleFunctionalReadNthEvent.py @@ -0,0 +1,41 @@ +# +# Copyright (c) 2014-2024 Key4hep-Project. +# +# This file is part of Key4hep. +# See https://key4hep.github.io/key4hep-doc/ for further info. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This is an example for reading from a file starting from a certain event and +# tranforming so that later we can check the number of events in the output file + +from Gaudi.Configuration import INFO +from Configurables import ExampleFunctionalTransformer +from Configurables import EventDataSvc +from k4FWCore import ApplicationMgr, IOSvc + +svc = IOSvc("IOSvc") +svc.Input = "functional_producer.root" +svc.Output = "functional_nth_event.root" +svc.FirstEventEntry = 7 + +consumer = ExampleFunctionalTransformer(Offset=0) + +mgr = ApplicationMgr( + TopAlg=[consumer], + EvtSel="NONE", + EvtMax=-1, + ExtSvc=[EventDataSvc("EventDataSvc")], + OutputLevel=INFO, +)