diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/DoubleEventSelectorAthenaPool.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/DoubleEventSelectorAthenaPool.cxx index 139a5a3154fad2cfe30bafc130fea90977195ccd..be9a39468d121824adca7f9d1363f77fca96349a 100644 --- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/DoubleEventSelectorAthenaPool.cxx +++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/DoubleEventSelectorAthenaPool.cxx @@ -83,7 +83,9 @@ StatusCode DoubleEventSelectorAthenaPool::next(IEvtSelector::Context& ctxt) cons if (!m_counterTool.empty() && !m_counterTool->preNext().isSuccess()) { ATH_MSG_WARNING("Failed to preNext() CounterTool."); } - if (m_evtCount > m_skipEvents && (m_skipEventSequence.empty() || m_evtCount != m_skipEventSequence.front())) { + if( m_evtCount > m_skipEvents + && (m_skipEventRanges.empty() || m_evtCount < m_skipEventRanges.front().first)) + { if (!recordAttributeList().isSuccess()) { ATH_MSG_ERROR("Failed to record AttributeList."); return(StatusCode::FAILURE); @@ -113,8 +115,8 @@ StatusCode DoubleEventSelectorAthenaPool::next(IEvtSelector::Context& ctxt) cons break; } } else { - if (!m_skipEventSequence.empty() && m_evtCount == m_skipEventSequence.front()) { - m_skipEventSequence.erase(m_skipEventSequence.begin()); + while( !m_skipEventRanges.empty() && m_evtCount >= m_skipEventRanges.front().second ) { + m_skipEventRanges.erase(m_skipEventRanges.begin()); } ATH_MSG_INFO("skipping event " << m_evtCount); } diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx index 40b72b28ef6b200ac57c0238f67baab5a128f2fc..33e519d421814bf1e1bb1dfc4cf53188807865cb 100644 --- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx +++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx @@ -79,6 +79,8 @@ StoreGateSvc* EventSelectorAthenaPool::eventStore() const { } return(m_activeStoreSvc->operator->()); } +#include <boost/tokenizer.hpp> +#include <sstream> //________________________________________________________________________________ StatusCode EventSelectorAthenaPool::initialize() { if (m_isSecondary.value()) { @@ -97,8 +99,37 @@ StatusCode EventSelectorAthenaPool::initialize() { << "[ \"<collectionName>\" ] (list of collections)"); return(StatusCode::FAILURE); } - m_skipEventSequence = m_skipEventSequenceProp.value(); - std::sort(m_skipEventSequence.begin(), m_skipEventSequence.end()); + boost::char_separator<char> sep_coma(","), sep_hyph("-"); + boost::tokenizer ranges(m_skipEventRangesProp.value(), sep_coma); + for( const std::string r: ranges ) { + boost::tokenizer fromto(r, sep_hyph); + auto from_iter = fromto.begin(); + std::stringstream strstr1( *from_iter ); + long from, to; + strstr1 >> from; + if( ++from_iter != fromto.end() ) { + std::stringstream strstr2( *from_iter ); + strstr2 >> to; + } else { + to = from; + } + m_skipEventRanges.push_back( std::pair(from,to) ); + } + + for( auto v : m_skipEventSequenceProp.value() ) { + m_skipEventRanges.push_back( std::pair(v,v) ); + } + std::sort(m_skipEventRanges.begin(), m_skipEventRanges.end()); + if( msgLvl(MSG::DEBUG) ) { + std::stringstream skip_ranges_ss; + for( auto& r: m_skipEventRanges ) { + if( not skip_ranges_ss.str().empty() ) skip_ranges_ss << ", "; + skip_ranges_ss << r.first; + if( r.first != r.second) skip_ranges_ss << "-" << r.second; + } + if( not skip_ranges_ss.str().empty() ) + ATH_MSG_DEBUG("Events to skip: " << skip_ranges_ss.str()); + } // CollectionType must be one of: if (m_collectionType.value() != "ExplicitROOT" && m_collectionType.value() != "ImplicitROOT") { ATH_MSG_FATAL("EventSelector.CollectionType must be one of: ExplicitROOT, ImplicitROOT (default)"); @@ -498,7 +529,9 @@ StatusCode EventSelectorAthenaPool::next(IEvtSelector::Context& ctxt) const { if (!m_counterTool.empty() && !m_counterTool->preNext().isSuccess()) { ATH_MSG_WARNING("Failed to preNext() CounterTool."); } - if (m_evtCount > m_skipEvents && (m_skipEventSequence.empty() || m_evtCount != m_skipEventSequence.front())) { + if( m_evtCount > m_skipEvents + && (m_skipEventRanges.empty() || m_evtCount < m_skipEventRanges.front().first)) + { if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isServer()) { std::string token = m_headerIterator->eventRef().toString(); StatusCode sc = m_eventStreamingTool->putEvent(m_evtCount - 1, token.c_str(), token.length() + 1, 0); @@ -548,8 +581,8 @@ StatusCode EventSelectorAthenaPool::next(IEvtSelector::Context& ctxt) const { break; } } else { - if (!m_skipEventSequence.empty() && m_evtCount == m_skipEventSequence.front()) { - m_skipEventSequence.erase(m_skipEventSequence.begin()); + while( !m_skipEventRanges.empty() && m_evtCount >= m_skipEventRanges.front().second ) { + m_skipEventRanges.erase(m_skipEventRanges.begin()); } ATH_MSG_INFO("skipping event " << m_evtCount); } diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.h b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.h index 2cfa32f009ea774107de35b1ccdb2ff356fb5737..b04379fd2cc361c19bd189b209a66697df9352c7 100644 --- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.h +++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.h @@ -198,7 +198,7 @@ private: // properties Gaudi::Property<std::vector<std::string>> m_inputCollectionsProp{this, "InputCollections", {}, ""}; mutable std::vector<std::string>::const_iterator m_inputCollectionsIterator ATLAS_THREAD_SAFE; void inputCollectionsHandler(Gaudi::Details::PropertyBase&); - /// Query, query string. + /// Query string passed to APR when opening DataHeader container (kind of useless). Gaudi::Property<std::string> m_query{this, "Query", "", ""}; /// KeepInputFilesOpen, boolean flag to keep files open after PoolCollection reaches end: default = false. @@ -233,7 +233,9 @@ private: // properties /// SkipEvents, numbers of events to skip: default = 0. Gaudi::Property<int> m_skipEvents{this, "SkipEvents", 0, ""}; Gaudi::Property<std::vector<long>> m_skipEventSequenceProp{this, "SkipEventSequence", {}, ""}; - mutable std::vector<long> m_skipEventSequence ATLAS_THREAD_SAFE; + /// Skip Events - comma separated list of event to skip, ranges with '-': <start> - <end> + Gaudi::Property<std::string> m_skipEventRangesProp{this, "SkipEventRanges", {}, ""}; + mutable std::vector<std::pair<long,long>> m_skipEventRanges ATLAS_THREAD_SAFE; mutable std::atomic_int m_evtCount{}; // internal count of events mutable std::atomic_bool m_firedIncident{};