24#include "GaudiKernel/ClassID.h"
25#include "GaudiKernel/FileIncident.h"
26#include "GaudiKernel/IIncidentSvc.h"
27#include "GaudiKernel/IIoComponentMgr.h"
28#include "GaudiKernel/GaudiException.h"
29#include "GaudiKernel/GenericAddress.h"
30#include "GaudiKernel/StatusCode.h"
45 base_class(name, pSvcLocator)
57 m_inputCollectionsChanged =
false;
61 if (this->FSMState() != Gaudi::StateMachine::OFFLINE) {
62 m_inputCollectionsChanged =
true;
75 m_autoRetrieveTools =
false;
76 m_checkToolDeps =
false;
79 ATH_MSG_DEBUG(
"Initializing secondary event selector " << name());
87 ATH_MSG_FATAL(
"Use the property: EventSelector.InputCollections = "
88 <<
"[ \"<collectionName>\" ] (list of collections)");
89 return StatusCode::FAILURE;
92 for(
const std::string&
r: ranges ) {
94 auto from_iter = fromto.begin();
95 long from = std::stol(*from_iter);
97 if( ++from_iter != fromto.end() ) {
98 to = std::stol(*from_iter);
100 m_skipEventRanges.emplace_back(from, to);
104 m_skipEventRanges.emplace_back(v, v);
106 std::sort(m_skipEventRanges.begin(), m_skipEventRanges.end());
107 if( msgLvl(MSG::DEBUG) ) {
108 std::string skip_ranges_str;
109 for(
const auto& [first, second] : m_skipEventRanges ) {
110 if( !skip_ranges_str.empty() ) skip_ranges_str +=
", ";
111 skip_ranges_str += std::to_string(first);
112 if( first != second) skip_ranges_str += std::format(
"-{}", second);
114 if( !skip_ranges_str.empty() )
130 std::vector<std::string> propVal;
132 bool foundCnvSvc =
false;
133 for (
const auto& property : propVal) {
138 if (!epSvc->setProperty(
"CnvServices", Gaudi::Utils::toString(propVal)).isSuccess()) {
139 ATH_MSG_FATAL(
"Cannot set EventPersistencySvc Property for CnvServices");
140 return StatusCode::FAILURE;
151 for (
const auto& inputCollection : incol) {
152 if (!iomgr->io_register(
this, IIoComponentMgr::IoMode::READ, inputCollection, inputCollection).isSuccess()) {
153 ATH_MSG_FATAL(
"could not register [" << inputCollection <<
"] for output !");
156 ATH_MSG_VERBOSE(
"io_register[" << this->name() <<
"](" << inputCollection <<
") [ok]");
160 return StatusCode::FAILURE;
166 return StatusCode::FAILURE;
170 if (!
reinit().isSuccess()) {
171 return StatusCode::FAILURE;
176 m_incidentSvc->addListener(
this, IncidentType::BeginProcessing, 0);
177 m_incidentSvc->addListener(
this, IncidentType::EndProcessing, 0);
178 return StatusCode::SUCCESS;
191 if (!m_firstEvt.empty()) {
194 m_inputCollectionsChanged =
false;
196 m_headerIterator = 0;
197 bool retError =
false;
198 for (
auto& tool : m_helperTools) {
199 if (!tool->postInitialize().isSuccess()) {
200 ATH_MSG_FATAL(
"Failed to postInitialize() " << tool->name());
206 return StatusCode::FAILURE;
211 if (!m_poolCollection) {
212 ATH_MSG_INFO(
"No Events found in any Input Collections");
218 FileIncident firstInputFileIncident(name(),
"FirstInputFile", *m_inputCollectionsIterator);
223 return StatusCode::SUCCESS;
227 m_headerIterator = m_poolCollection->cursor();
228 }
catch (std::exception &e) {
229 ATH_MSG_FATAL(
"Cannot open input collection - check data/software version.");
231 return StatusCode::FAILURE;
233 while (m_headerIterator ==
nullptr || m_headerIterator->next() == 0) {
236 m_poolCollection =
nullptr;
239 ++m_inputCollectionsIterator;
242 if (m_poolCollection) {
243 m_headerIterator = m_poolCollection->cursor();
248 if (!m_poolCollection || m_headerIterator ==
nullptr) {
252 if (!m_poolCollection) {
253 return StatusCode::SUCCESS;
255 m_headerIterator = m_poolCollection->cursor();
256 while (m_headerIterator ==
nullptr || m_headerIterator->next() == 0) {
258 ++m_inputCollectionsIterator;
260 if (m_poolCollection) {
261 m_headerIterator = m_poolCollection->cursor();
267 if (!m_poolCollection || m_headerIterator ==
nullptr) {
268 return StatusCode::SUCCESS;
270 const Token& headRef = m_headerIterator->eventRef();
277 FileIncident firstInputFileIncident(name(),
"FirstInputFile",
"FID:" + fid, fid);
281 return StatusCode::SUCCESS;
289 if (!m_poolCollection) {
290 ATH_MSG_INFO(
"No Events found in any Input Collections");
293 --m_inputCollectionsIterator;
296 m_headerIterator = m_poolCollection->cursor();
302 return StatusCode::SUCCESS;
308 m_inputFileGuard.reset();
310 IEvtSelector::Context* ctxt(
nullptr);
314 return StatusCode::SUCCESS;
322 for (
auto& tool : m_helperTools) {
323 if (!tool->preFinalize().isSuccess()) {
328 m_headerIterator =
nullptr;
329 m_poolCollection.reset();
330 m_curCollectionName.clear();
332 return ::AthService::finalize();
338 return StatusCode::SUCCESS;
342 std::lock_guard<CallMutex> lockGuard(
m_callLock);
343 for (
const auto& tool : m_helperTools) {
344 if (!tool->preNext().isSuccess()) {
351 if (
sc.isRecoverable()) {
354 if (
sc.isFailure()) {
355 return StatusCode::FAILURE;
363 && (m_skipEventRanges.empty() ||
m_evtCount < m_skipEventRanges.front().first))
368 return StatusCode::FAILURE;
371 StatusCode status = StatusCode::SUCCESS;
372 for (
const auto& tool : m_helperTools) {
373 StatusCode toolStatus = tool->postNext();
374 if (toolStatus.isRecoverable()) {
375 ATH_MSG_INFO(
"Request skipping event from: " << tool->name());
376 if (status.isSuccess()) {
377 status = StatusCode::RECOVERABLE;
379 }
else if (toolStatus.isFailure()) {
381 status = StatusCode::FAILURE;
384 if (status.isRecoverable()) {
386 }
else if (status.isFailure()) {
395 while( !m_skipEventRanges.empty() &&
m_evtCount >= m_skipEventRanges.front().second ) {
396 m_skipEventRanges.erase(m_skipEventRanges.begin());
401 return StatusCode::SUCCESS;
406 for (
int i = 0; i < jump; i++) {
409 return StatusCode::SUCCESS;
411 return StatusCode::FAILURE;
416 if( m_inputCollectionsChanged ) {
418 if(
rc != StatusCode::SUCCESS )
return rc;
422 if (m_headerIterator ==
nullptr || m_headerIterator->next() == 0) {
423 m_headerIterator =
nullptr;
425 m_poolCollection.reset();
428 m_inputFileGuard.reset();
434 if( m_inputCollectionsChanged ) {
436 if(
rc != StatusCode::SUCCESS )
return rc;
440 m_poolCollection =
nullptr;
443 ++m_inputCollectionsIterator;
447 if (!m_poolCollection) {
451 return StatusCode::FAILURE;
454 m_headerIterator = m_poolCollection->cursor();
457 return StatusCode::RECOVERABLE;
461 const Token& headRef = m_headerIterator->eventRef();
465 if (guid != m_guid) {
475 m_activeEventsPerSource[guid.toString()] = 0;
476 if (!
m_athenaPoolCnvSvc->setInputAttributes(*m_inputCollectionsIterator).isSuccess()) {
478 return StatusCode::FAILURE;
482 *m_inputCollectionsIterator, m_guid.toString(),
486 return StatusCode::SUCCESS;
495 if (
sc.isRecoverable()) {
498 if (
sc.isFailure()) {
499 return StatusCode::FAILURE;
509 && (m_skipEventRanges.empty() ||
m_evtCount < m_skipEventRanges.front().first))
511 return StatusCode::SUCCESS;
513 while( !m_skipEventRanges.empty() &&
m_evtCount >= m_skipEventRanges.front().second ) {
514 m_skipEventRanges.erase(m_skipEventRanges.begin());
524 return StatusCode::SUCCESS;
529 return StatusCode::FAILURE;
534 for (
int i = 0; i < jump; i++) {
537 return StatusCode::SUCCESS;
539 return StatusCode::FAILURE;
543 if (ctxt.identifier() ==
m_endIter->identifier()) {
545 return StatusCode::SUCCESS;
547 return StatusCode::FAILURE;
553 return StatusCode::SUCCESS;
557 IOpaqueAddress*& iop)
const {
558 std::string tokenStr;
562 tokenStr = (*attrList)[
"eventRef"].data<std::string>();
563 ATH_MSG_DEBUG(
"found AthenaAttribute, name = eventRef = " << tokenStr);
564 }
catch (std::exception &e) {
566 return StatusCode::FAILURE;
570 tokenStr = m_headerIterator->eventRef().toString();
572 auto token = std::make_unique<Token>();
573 token->fromString(tokenStr);
574 m_incidentSvc->fireIncident(Incident(tokenStr,
"ProcessEventAttributes"));
576 return StatusCode::SUCCESS;
580 return StatusCode::SUCCESS;
584 IEvtSelector::Context& )
const {
585 return StatusCode::SUCCESS;
590 if( m_inputCollectionsChanged ) {
592 if(
rc != StatusCode::SUCCESS )
return rc;
600 m_headerIterator =
nullptr;
602 m_inputFileGuard.reset();
603 return StatusCode::RECOVERABLE;
609 m_poolCollection.reset();
615 <<
"\" from the collection list.");
621 if (!
sc.isSuccess() || !m_poolCollection) {
622 m_headerIterator =
nullptr;
624 return StatusCode::FAILURE;
626 m_curCollectionName = collName;
628 m_headerIterator = m_poolCollection->cursor();
631 next(*beginIter).ignore();
632 ATH_MSG_DEBUG(
"Token " << m_headerIterator->eventRef().toString());
633 }
catch (std::exception &e) {
634 m_headerIterator =
nullptr;
636 return StatusCode::FAILURE;
640 if (m_headerIterator->seek(evtNum - m_firstEvt[
m_curCollection]) == 0) {
641 m_headerIterator =
nullptr;
643 return StatusCode::FAILURE;
647 return StatusCode::SUCCESS;
659 for (std::size_t i = 0,
imax = m_numEvt.size(); i <
imax; i++) {
660 if (m_numEvt[i] == -1) {
662 std::string lastError;
663 std::unique_ptr<pool::Collection> coll;
665 if (!status.isSuccess()) {
668 int collection_size = 0;
670 std::unique_ptr<pool::CollectionCursor> hi = coll->cursor();
671 collection_size = hi->size();
677 m_firstEvt[i] = m_firstEvt[i - 1] + m_numEvt[i - 1];
681 m_numEvt[i] = collection_size;
683 if (evtNum >= m_firstEvt[i] && evtNum < m_firstEvt[i] + m_numEvt[i]) {
694 return std::accumulate(m_numEvt.begin(), m_numEvt.end(), 0);
698 std::unique_ptr<pool::Collection>& poolCollection,
699 std::string* lastError)
const {
700 if (!inputCollection.starts_with(
"PFN:")
701 && !inputCollection.starts_with(
"LFN:")
702 && !inputCollection.starts_with(
"FID:")) {
703 inputCollection = std::format(
"PFN:{}", inputCollection);
708 poolCollection = std::make_unique<pool::Collection>(fileDescr);
709 if (lastError) lastError->clear();
710 }
catch (
const std::exception &e) {
712 *lastError = std::format(
"Failed to open collection '{}': {}", inputCollection, e.what());
714 poolCollection.reset();
716 if (
sc.isRecoverable() || poolCollection ==
nullptr) {
719 return StatusCode::SUCCESS;
723 if (m_poolCollection) {
724 if (!m_curCollectionName.empty()) {
725 m_poolSvc->disconnectDb(m_curCollectionName).ignore();
726 m_curCollectionName.clear();
728 m_poolCollection.reset();
732std::unique_ptr<pool::Collection>
740 ATH_MSG_DEBUG(
"Try item: \"" << *m_inputCollectionsIterator <<
"\" from the collection list.");
741 std::string collName = *m_inputCollectionsIterator;
742 std::unique_ptr<pool::Collection> coll;
744 if (!status.isSuccess()) {
745 if (!status.isRecoverable()) {
747 throw GaudiException(
"Unable to read: " + *m_inputCollectionsIterator, name(), StatusCode::FAILURE);
749 ATH_MSG_ERROR(
"Unable to open: " << *m_inputCollectionsIterator);
750 throw GaudiException(
"Unable to open: " + *m_inputCollectionsIterator, name(), StatusCode::FAILURE);
754 ATH_MSG_DEBUG(
"No events found in: " << *m_inputCollectionsIterator <<
" skipped!!!");
758 *m_inputCollectionsIterator, {},
759 "eventless " + *m_inputCollectionsIterator);
761 m_poolSvc->disconnectDb(*m_inputCollectionsIterator).ignore();
762 ++m_inputCollectionsIterator;
764 m_curCollectionName = collName;
773 if (!
eventStore()->clearStore().isSuccess()) {
779 const coral::AttributeList& attrList = m_headerIterator->currentRow().attributeList();
786 ATH_CHECK(wh.record(std::move(athAttrList)));
787 return StatusCode::SUCCESS;
792 const auto& row = m_headerIterator->currentRow();
793 attrList->extend( row.tokenName() + suffix,
"string" );
794 (*attrList)[ row.tokenName() + suffix ].data<std::string>() = row.token().toString();
795 ATH_MSG_DEBUG(
"record AthenaAttribute, name = " << row.tokenName() + suffix <<
" = " << row.token().toString() <<
".");
797 std::string eventRef =
"eventRef";
799 eventRef.append(suffix);
801 attrList->extend(eventRef,
"string");
802 (*attrList)[eventRef].data<std::string>() = m_headerIterator->eventRef().toString();
803 ATH_MSG_DEBUG(
"record AthenaAttribute, name = " + eventRef +
" = " << m_headerIterator->eventRef().toString() <<
".");
806 const coral::AttributeList& sourceAttrList = m_headerIterator->currentRow().attributeList();
807 for (
const auto &attr : sourceAttrList) {
808 attrList->extend(attr.specification().name() + suffix, attr.specification().type());
809 (*attrList)[attr.specification().name() + suffix] = attr;
813 return StatusCode::SUCCESS;
819 m_headerIterator =
nullptr;
821 if (!iomgr.retrieve().isSuccess()) {
823 return StatusCode::FAILURE;
825 if (!iomgr->io_hasitem(
this)) {
826 ATH_MSG_FATAL(
"IoComponentMgr does not know about myself !");
827 return StatusCode::FAILURE;
830 std::set<std::size_t> updatedIndexes;
832 if (updatedIndexes.find(i) != updatedIndexes.end())
continue;
833 std::string savedName = inputCollections[i];
834 std::string &fname = inputCollections[i];
835 if (!iomgr->io_contains(
this, fname)) {
836 ATH_MSG_ERROR(
"IoComponentMgr does not know about [" << fname <<
"] !");
837 return StatusCode::FAILURE;
839 if (!iomgr->io_retrieve(
this, fname).isSuccess()) {
840 ATH_MSG_FATAL(
"Could not retrieve new value for [" << fname <<
"] !");
841 return StatusCode::FAILURE;
843 updatedIndexes.insert(i);
844 for (std::size_t j = i + 1; j <
imax; j++) {
845 if (inputCollections[j] == savedName) {
846 inputCollections[j] = fname;
847 updatedIndexes.insert(j);
860 m_inputFileGuard.reset();
862 return StatusCode::SUCCESS;
874 if (inc.type() == IncidentType::BeginProcessing) {
885 ATH_MSG_WARNING(
"could not read event source ID from incident event context");
888 if( m_activeEventsPerSource.find( fid ) == m_activeEventsPerSource.end()) {
889 ATH_MSG_DEBUG(
"Incident handler ignoring unknown input FID: " << fid );
892 ATH_MSG_DEBUG(
"** MN Incident handler " << inc.type() <<
" Event source ID=" << fid );
893 if( inc.type() == IncidentType::BeginProcessing ) {
895 m_activeEventsPerSource[fid]++;
896 }
else if( inc.type() == IncidentType::EndProcessing ) {
897 m_activeEventsPerSource[fid]--;
901 if( msgLvl(MSG::DEBUG) ) {
902 for(
auto& source: m_activeEventsPerSource )
903 msg(MSG::DEBUG) <<
"SourceID: " << source.first <<
" active events: " << source.second <<
endmsg;
914 if( m_activeEventsPerSource.find(fid) != m_activeEventsPerSource.end()
915 && m_activeEventsPerSource[fid] <= 0 && m_guid != fid ) {
921 m_activeEventsPerSource.erase( fid );
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
This file contains the class definition for the EventContextAthenaPool class.
This file contains the class definition for the EventSelectorAthenaPool class.
This file contains the class definition for the IPoolSvc interface class.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
This file contains the class definition for the TokenAddress class.
This file contains the class definition for the Token class (migrated from POOL).
An AttributeList represents a logical row of attributes in a metadata table.
This class provides the context to access an event from POOL persistent store.
EventSelectorAthenaPool(const std::string &name, ISvcLocator *pSvcLocator)
Standard Service Constructor.
Gaudi::CheckedProperty< uint64_t > m_firstEventNo
virtual StatusCode start() override
Gaudi::Property< bool > m_isSecondary
IsSecondary, know if this is an instance of secondary event selector.
virtual StatusCode nextWithSkip(IEvtSelector::Context &ctxt) const override
Go to next event and skip if necessary.
std::unique_ptr< pool::Collection > getCollection(bool throwIncidents=false) const
Return pointer to new Collection.
virtual StatusCode initialize() override
Required of all Gaudi Services.
Gaudi::Property< int > m_skipEvents
SkipEvents, numbers of events to skip: default = 0.
Gaudi::Property< bool > m_processMetadata
ProcessMetadata, switch on firing of FileIncidents which will trigger processing of metadata: default...
virtual int curEvent(const Context &ctxt) const override
Return the current event number.
virtual StatusCode createContext(IEvtSelector::Context *&ctxt) const override
create context
virtual StatusCode io_finalize() override
Callback method to finalize the internal state of the component for I/O purposes (e....
Gaudi::Property< std::vector< long > > m_skipEventSequenceProp
Gaudi::CheckedProperty< uint32_t > m_initTimeStamp
void inputCollectionsHandler(Gaudi::Details::PropertyBase &)
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
virtual StatusCode resetCriteria(const std::string &criteria, IEvtSelector::Context &ctxt) const override
Set a selection criteria.
StatusCode reinit() const
Reinitialize the service when a fork() occurred/was-issued.
StoreGateSvc * eventStore() const
Return pointer to active event SG.
virtual StatusCode releaseContext(IEvtSelector::Context *&ctxt) const override
virtual StatusCode stop() override
ServiceHandle< IIncidentSvc > m_incidentSvc
virtual StatusCode next(IEvtSelector::Context &ctxt) const override
virtual ~EventSelectorAthenaPool()
Destructor.
ToolHandle< IAthenaSelectorTool > m_counterTool
ServiceHandle< IPoolSvc > m_poolSvc
virtual StatusCode fillAttributeList(coral::AttributeList *attrList, const std::string &suffix, bool copySource) const override
Fill AttributeList with specific items from the selector and a suffix.
std::string m_attrListKey
AttributeList SG key.
virtual StatusCode seek(Context &ctxt, int evtnum) const override
Seek to a given event number.
SG::SlotSpecificObj< SG::SourceID > m_sourceID
virtual StatusCode last(IEvtSelector::Context &ctxt) const override
Gaudi::CheckedProperty< uint64_t > m_eventsPerRun
Gaudi::CheckedProperty< uint32_t > m_eventsPerLB
virtual StatusCode createAddress(const IEvtSelector::Context &ctxt, IOpaqueAddress *&iop) const override
virtual void handle(const Incident &incident) override
Incident service handle listening for BeginProcessing and EndProcessing.
virtual StatusCode previous(IEvtSelector::Context &ctxt) const override
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
virtual StatusCode rewind(IEvtSelector::Context &ctxt) const override
Gaudi::Property< bool > m_keepInputFilesOpen
KeepInputFilesOpen, boolean flag to keep files open after PoolCollection reaches end: default = false...
void disconnectCollection() const
Disconnect current collection DB if open.
Gaudi::CheckedProperty< uint32_t > m_oldRunNo
virtual StatusCode finalize() override
virtual bool disconnectIfFinished(const SG::SourceID &fid) const override
Disconnect DB if all events from the source FID were processed and the Selector moved to another file...
Gaudi::Property< std::vector< std::string > > m_inputCollectionsProp
InputCollections, vector with names of the input collections.
EventContextAthenaPool * m_endIter
std::atomic_int m_evtCount
std::atomic_bool m_firedIncident
StatusCode openCollection(std::string &inputCollection, std::unique_ptr< pool::Collection > &poolCollection, std::string *lastError=nullptr) const
Open a collection by name.
std::atomic_long m_curCollection
virtual StatusCode nextHandleFileTransition(IEvtSelector::Context &ctxt) const override
Handle file transition at the next iteration.
virtual StatusCode recordAttributeList() const override
Record AttributeList in StoreGate.
Gaudi::CheckedProperty< uint32_t > m_runNo
The following are included for compatibility with McEventSelector and are not really used.
virtual int size(Context &ctxt) const override
Return the size of the collection.
int findEvent(int evtNum) const
Search for event with number evtNum.
Gaudi::Property< std::string > m_skipEventRangesProp
Skip Events - comma separated list of event to skip, ranges with '-': <start> - <end>.
Gaudi::CheckedProperty< uint32_t > m_firstLBNo
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
static const Guid & null() noexcept
NULL-Guid: static class method.
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
The Athena Transient Store API.
static StoreGateSvc * currentStoreGate()
get current StoreGate
This class provides a Generic Transient Address for POOL tokens.
This class provides a token that identifies in a unique way objects on the persistent storage.
const std::string toString() const
Retrieve the string representation of the token.
int technology() const
Access technology type.
const Guid & dbID() const
Access database identifier.
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
bool hasExtendedEventContext(const EventContext &ctx)
Test whether a context object has an extended context installed.
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
static const DbType POOL_StorageType
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
static constexpr CLID ID()