ATLAS Offline Software
Loading...
Searching...
No Matches
EventSelectorByteStream.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <vector>
8#include <algorithm>
9
14
15#include "GaudiKernel/ClassID.h"
16#include "GaudiKernel/FileIncident.h"
17#include "GaudiKernel/IIncidentSvc.h"
18#include "GaudiKernel/IIoComponentMgr.h"
19
23
24// EventInfoAttributeList includes
27#include "eformat/StreamTag.h"
28
29
30namespace {
31 const std::string stringTypeStr{"string"};
33 StatusCode putEvent_ST(const IAthenaIPCTool& tool,
34 long eventNumber, const void* source,
35 size_t nbytes, unsigned int status) {
36 StatusCode sc ATLAS_THREAD_SAFE = tool.putEvent(eventNumber, source, nbytes, status);
37 return sc;
38 }
39}
40
41
42// Constructor.
44 ISvcLocator *svcloc)
45 : base_class(name, svcloc) {
46 // RunNumber, OldRunNumber and OverrideRunNumberFromInput are used
47 // to override the run number coming in on the input stream
48 m_runNo.verifier().setLower(0);
49 // The following properties are only for compatibility with
50 // McEventSelector and are not really used anywhere
51 // TODO(berghaus): validate if those are even used
52 m_eventsPerRun.verifier().setLower(0);
53 m_firstEventNo.verifier().setLower(1);
54 m_firstLBNo.verifier().setLower(0);
55 m_eventsPerLB.verifier().setLower(0);
56 m_initTimeStamp.verifier().setLower(0);
57
58 m_inputCollectionsProp.declareUpdateHandler(
60}
61
62/******************************************************************************/
63void EventSelectorByteStream::inputCollectionsHandler(Gaudi::Details::PropertyBase&) {
65 if (this->FSMState() != Gaudi::StateMachine::OFFLINE) {
66 this->reinit(lock).ignore();
67 }
68}
69
70
71/******************************************************************************/
74
75
76/******************************************************************************/
81
82
83//________________________________________________________________________________
85
86 m_autoRetrieveTools = false;
87 m_checkToolDeps = false;
88
89 if (m_isSecondary.value()) {
90 ATH_MSG_DEBUG("Initializing secondary event selector " << name());
91 } else {
92 ATH_MSG_DEBUG("Initializing " << name());
93 }
94
95 ATH_CHECK(::AthService::initialize());
96
97 // Check for input setting
98 if (m_filebased && m_inputCollectionsProp.value().empty()) {
99 ATH_MSG_FATAL("Unable to retrieve valid input list");
100 return StatusCode::FAILURE;
101 }
102 m_skipEventSequence = m_skipEventSequenceProp.value();
103 std::sort(m_skipEventSequence.begin(), m_skipEventSequence.end());
104
105 // Check ByteStreamCnvSvc
106 m_eventSource = serviceLocator()->service(m_eventSourceName.value());
107 if (!m_eventSource) {
108 ATH_MSG_FATAL("Cannot get ByteStreamInputSvc");
109 return StatusCode::FAILURE;
110 }
111
112 // Get CounterTool (if configured)
113 if (!m_counterTool.empty()) {
114 ATH_CHECK(m_counterTool.retrieve());
115 }
116 // Get HelperTools
117 if (!m_helperTools.empty()) {
118 ATH_CHECK(m_helperTools.retrieve());
119 }
120 // Get SharedMemoryTool (if configured)
121 if (!m_eventStreamingTool.empty()) {
122 ATH_CHECK(m_eventStreamingTool.retrieve());
123 }
124
125 // Register this service for 'I/O' events
126 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
127 ATH_CHECK(iomgr.retrieve());
128 ATH_CHECK(iomgr->io_register(this));
129
130 // Register the input files with the iomgr
131 bool allGood = true;
132 for (const std::string& input : m_inputCollectionsProp.value()) {
133 if (!iomgr->io_register(this, IIoComponentMgr::IoMode::READ, input).isSuccess()) {
134 ATH_MSG_FATAL("could not register [" << input << "] for output !");
135 allGood = false;
136 } else {
137 ATH_MSG_VERBOSE("io_register[" << this->name() << "](" << input << ") [ok]");
138 }
139 }
140 if (!allGood) {
141 return(StatusCode::FAILURE);
142 }
143
144 // Make sure MetaDataSvc is initialized before the first file is opened
145 ServiceHandle<IAthMetaDataSvc> metaDataSvc("MetaDataSvc", name());
146 ATH_CHECK(metaDataSvc.retrieve());
147
148 // Must happen before trying to open a file
150 StatusCode risc = this->reinit(lock);
151
152 return risc;
153}
154//__________________________________________________________________________
156 ATH_MSG_INFO("reinitialization...");
157 // reset markers
158 if (m_inputCollectionsProp.value().size()>0) {
159 m_numEvt.resize(m_inputCollectionsProp.value().size(), -1);
160 m_firstEvt.resize(m_inputCollectionsProp.value().size(), -1);
161 }
162 else {
163 m_numEvt.resize(1);
164 m_firstEvt.resize(1);
165 }
166
167 // Initialize InputCollectionsIterator
168 m_inputCollectionsIterator = m_inputCollectionsProp.value().begin();
169 m_NumEvents = 0;
170 bool retError = false;
171 if (!m_helperTools.empty()) {
172 for (ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
173 if (!tool->postInitialize().isSuccess()) {
174 ATH_MSG_FATAL("Failed to postInitialize() " << tool->name());
175 retError = true;
176 }
177 }
178 }
179 if (retError) {
180 ATH_MSG_FATAL("Failed to postInitialize() helperTools");
181 return(StatusCode::FAILURE);
182 }
183
184 // If file based input then fire appropriate incidents
185 if (m_filebased) {
186 if (!m_firstFileFired) {
187 FileIncident firstInputFileIncident(name(), "FirstInputFile", "BSF:" + *m_inputCollectionsIterator);
188 m_incidentSvc->fireIncident(firstInputFileIncident);
189 m_firstFileFired = true;
190 }
191
192 // try to open a file
193 ATH_CHECK(this->openNewRun(lock));
194 }
195
196 return StatusCode::SUCCESS;
197}
198
199//________________________________________________________________________________
201 ATH_MSG_DEBUG("Calling EventSelectorByteStream::start()");
203 // Create the begin and end iterator's for this selector.
205 // Increment to get the new event in.
207
208 return StatusCode::SUCCESS;
209}
210
211//________________________________________________________________________________
213 ATH_MSG_DEBUG("Calling EventSelectorByteStream::stop()");
214 if (m_filebased) {
215 // Fire EndInputFile for any file still open
216 m_inputFileGuard.reset();
217 m_pendingFile.reset();
218 if (m_eventSource->ready()) {
219 m_eventSource->closeBlockIterator(false);
220 }
221 }
222 return StatusCode::SUCCESS;
223}
224
225//__________________________________________________________________________
227 if (!m_counterTool.empty()) {
228 if (!m_counterTool->preFinalize().isSuccess()) {
229 ATH_MSG_WARNING("Failed to preFinalize() CounterTool");
230 }
231 }
232 for (ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
233 if (!tool->preFinalize().isSuccess()) {
234 ATH_MSG_WARNING("Failed to preFinalize() " << tool->name());
235 }
236 }
237 delete m_beginIter; m_beginIter = nullptr;
238 delete m_endIter; m_endIter = nullptr;
239 if (m_eventSource) m_eventSource->release();
240 // Finalize the Service base class.
241 return AthService::finalize();
242}
243
245 // EndInputFile as soon as the file is done, also the last one: AthenaMP's event counter
246 // queues the last partial chunk on it, before it marks the end of the queue
247 m_inputFileGuard.reset();
248 m_pendingFile.reset();
249 ++m_inputCollectionsIterator;
250 ++m_fileCount;
251}
252
254 // Should be protected upstream, but this is further protection
255 if (!m_filebased) {
256 ATH_MSG_ERROR("cannot open new run for non-filebased inputs");
257 return StatusCode::FAILURE;
258 }
259 // Check for end of file list
260 if (m_inputCollectionsIterator == m_inputCollectionsProp.value().end()) {
261 ATH_MSG_INFO("End of input file list reached");
262 return StatusCode::FAILURE;
263 }
264 std::string blockname = *m_inputCollectionsIterator;
265 // try to open a file
266 long nev = openBlock(blockname, lock);
267 if (nev == -1) {
268 ATH_MSG_FATAL("Unable to access file " << *m_inputCollectionsIterator << ", stopping here");
270 }
271
272 // check if file is empty
273 if (nev == 0) {
274 ATH_MSG_WARNING("no events in file " << blockname << " try next");
276 if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true);
277 this->nextFile(lock);
278 return openNewRun(lock);
279 // check if skipping all events in that file (minus events already skipped)
280 } else if (m_skipEvents.value() - m_NumEvents > nev) {
281 ATH_MSG_WARNING("skipping more events " << m_skipEvents.value() - m_NumEvents << "(" << nev <<") than in file " << *m_inputCollectionsIterator << ", try next");
282 m_NumEvents += nev;
283 m_numEvt[m_fileCount] = nev;
285 if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true);
286 this->nextFile(lock);
287 return openNewRun(lock);
288 }
289
290 ATH_MSG_DEBUG("Opened block/file " << blockname);
291 m_firstEvt[m_fileCount] = m_NumEvents;
292 m_numEvt[m_fileCount] = nev;
293
294 return StatusCode::SUCCESS;
295}
296
297long EventSelectorByteStream::openBlock(const std::string& fileName, lock_t& /*lock*/) const {
298 auto nevguid = m_eventSource->getBlockIterator(fileName);
299 if (nevguid.first != -1) {
300 m_pendingFile.emplace("BSF:" + fileName, nevguid.second);
301 }
302 return nevguid.first;
303}
304
306 if (m_pendingFile) {
307 // EndInputFile for the previous file (if any), then BeginInputFile for this one
308 InputFileIncidentGuard::transition(m_inputFileGuard, *m_incidentSvc, name(),
309 m_pendingFile->first, m_pendingFile->second,
310 /*endFileName=*/{});
311 m_pendingFile.reset();
312 }
313}
314
315StatusCode EventSelectorByteStream::createContext(IEvtSelector::Context*& it) const {
316 it = new EventContextByteStream(this);
317 return StatusCode::SUCCESS;
318}
319
320StatusCode EventSelectorByteStream::next(IEvtSelector::Context& it) const {
322 return nextImpl (it, lock);
323}
324StatusCode EventSelectorByteStream::nextImpl(IEvtSelector::Context& it,
325 lock_t& lock) const
326{
327 static std::atomic<int> n_bad_events = 0; // cross loop counter of bad events
328 // Check if this is an athenaMP client process
329 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) {
330 void* source = nullptr;
331 unsigned int status = 0;
332 ATH_CHECK(m_eventStreamingTool->getLockedEvent(&source, status));
333 m_eventSource->setEvent(static_cast<char*>(source), status);
334 return StatusCode::SUCCESS;
335 }
336 // Call all selector tool preNext before starting loop
337 for (const ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
338 if (!tool->preNext().isSuccess()) {
339 ATH_MSG_WARNING("Failed to preNext() " << tool->name());
340 }
341 }
342 if (!m_counterTool.empty()) {
343 if (!m_counterTool->preNext().isSuccess()) {
344 ATH_MSG_WARNING("Failed to preNext() CounterTool.");
345 }
346 }
347 // Find an event to return
348 for (;;) {
349 bool badEvent{};
351 if (sc.isRecoverable()) {
352 badEvent = true;
353 } else if (sc.isFailure()) {
354 return StatusCode::FAILURE;
355 }
356
357 // increment that an event was found
358 ++m_NumEvents;
359
360 // check bad event flag and handle as configured
361 if (badEvent) {
362 int nbad = ++n_bad_events;
363 ATH_MSG_WARNING("Bad event encountered, current count at " << nbad);
364 bool toomany = (m_maxBadEvts >= 0 && nbad > m_maxBadEvts);
365 if (!m_procBadEvent || toomany) {
366 ATH_MSG_ERROR("Cannot continue processing: bad event handling disabled or limit exceeded (" << nbad << " events)");
367 it = *m_endIter;
368 return StatusCode::FAILURE;
369 }
370 ATH_MSG_WARNING("Continue with bad event");
371 }
372
373 // Check whether properties or tools reject this event
374 if ( m_NumEvents > m_skipEvents.value() &&
375 (m_skipEventSequence.empty() || m_NumEvents != m_skipEventSequence.front()) ) {
376
377 // Build a DH for use by other components
378 StatusCode rec_sg = m_eventSource->generateDataHeader();
379 if (rec_sg != StatusCode::SUCCESS) {
380 ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg);
381 }
382
383 // Build event info attribute list
384 if (recordAttributeListImpl(lock).isFailure()) ATH_MSG_WARNING("Unable to build event info att list");
385
386 StatusCode status(StatusCode::SUCCESS);
387 for (const ToolHandle<IAthenaSelectorTool>& tool : m_helperTools) {
388 StatusCode toolStatus = tool->postNext();
389 if (toolStatus.isRecoverable()) {
390 ATH_MSG_INFO("Request skipping event from: " << tool->name());
391 status = StatusCode::RECOVERABLE;
392 } else if (toolStatus.isFailure()) {
393 ATH_MSG_WARNING("Failed to postNext() " << tool->name());
394 status = StatusCode::FAILURE;
395 }
396 }
397 if (status.isRecoverable()) {
398 ATH_MSG_INFO("skipping event " << m_NumEvents);
399 } else if (status.isFailure()) {
400 ATH_MSG_WARNING("Failed to postNext() HelperTool.");
401 } else {
402 if (!m_counterTool.empty()) {
403 if (!m_counterTool->postNext().isSuccess()) {
404 ATH_MSG_WARNING("Failed to postNext() CounterTool.");
405 }
406 }
407 // Validate the event
408 try {
409 m_eventSource->validateEvent();
410 }
411 catch (const ByteStreamExceptions::badFragmentData&) {
412 int nbad = ++n_bad_events;
413 ATH_MSG_WARNING("Bad fragment data encountered, current count at " << nbad);
414
415 bool toomany = (m_maxBadEvts >= 0 && nbad > m_maxBadEvts);
416 if (!m_procBadEvent || toomany) {
417 ATH_MSG_ERROR("Cannot continue processing: bad event handling disabled or limit exceeded (" << nbad << " events)");
418 it = *m_endIter;
419 return StatusCode::FAILURE;
420 }
421 ATH_MSG_WARNING("Continue with bad event");
422 }
423 break;
424 }
425 } else {
426 if (!m_skipEventSequence.empty() && m_NumEvents == m_skipEventSequence.front()) {
427 m_skipEventSequence.erase(m_skipEventSequence.begin());
428 }
429 if ( m_NumEvents % 1'000 == 0 ) {
430 ATH_MSG_INFO("Skipping event " << m_NumEvents - 1);
431 } else {
432 ATH_MSG_DEBUG("Skipping event " << m_NumEvents - 1);
433 }
434 }
435 } // for loop
436
437 if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isServer()) { // For SharedReader Server, put event into SHM
438 const RawEvent* pre = m_eventSource->currentEvent();
440 while ( (sc = putEvent_ST(*m_eventStreamingTool,
441 m_NumEvents - 1, pre->start(),
442 pre->fragment_size_word() * sizeof(uint32_t),
443 m_eventSource->currentEventStatus())).isRecoverable() ) {
444 usleep(1000);
445 }
446 ATH_CHECK(sc);
447 }
448 return StatusCode::SUCCESS;
449}
450
451//________________________________________________________________________________
452StatusCode EventSelectorByteStream::next(IEvtSelector::Context& ctxt, int jump) const {
454 return nextImpl (ctxt, jump, lock);
455}
456//________________________________________________________________________________
458EventSelectorByteStream::nextImpl(IEvtSelector::Context& ctxt,
459 int jump,
460 lock_t& lock) const
461{
462 if (jump > 0) {
463 if ( m_NumEvents+jump != m_skipEvents.value()) {
464 // Save initial event count
465 unsigned int cntr = m_NumEvents;
466 // In case NumEvents increments multiple times in a single next call
467 while (m_NumEvents+1 <= cntr + jump) {
468 ATH_CHECK(nextImpl(ctxt, lock));
469 }
470 }
471 else ATH_MSG_DEBUG("Jump covered by skip event " << m_skipEvents.value());
472 return StatusCode::SUCCESS;
473 }
474 else {
475 ATH_MSG_WARNING("Called jump next with non-multiple jump");
476 }
477 return StatusCode::SUCCESS;
478}
479
480//________________________________________________________________________________
481StatusCode EventSelectorByteStream::nextHandleFileTransition(IEvtSelector::Context& ctxt) const
482{
484 return nextHandleFileTransitionImpl (ctxt, lock);
485}
486StatusCode EventSelectorByteStream::nextHandleFileTransitionImpl(IEvtSelector::Context& ctxt,
487 lock_t& lock) const
488{
489 const RawEvent* pre{};
490 bool badEvent{};
491 // if event source not ready from init, try next file
492 if (m_filebased && !m_eventSource->ready()) {
493 // next file
494 this->nextFile(lock);
495 if (this->openNewRun(lock).isFailure()) {
496 ATH_MSG_DEBUG("Event source found no more valid files left in input list");
497 m_NumEvents = -1;
498 return StatusCode::FAILURE;
499 }
500 }
501 try {
502 pre = m_eventSource->nextEvent();
503 }
504 catch (const ByteStreamExceptions::readError&) {
505 ATH_MSG_FATAL("Caught ByteStreamExceptions::readError");
506 return StatusCode::FAILURE;
507 }
508 catch (const ByteStreamExceptions::badFragment&) {
509 ATH_MSG_ERROR("badFragment encountered");
510 badEvent = true;
511 }
513 ATH_MSG_ERROR("badFragment data encountered");
514 badEvent = true;
515 }
516 // Check whether a RawEvent has actually been provided
517 if (pre == nullptr) {
518 ctxt = *m_endIter;
519 return StatusCode::FAILURE;
520 }
521 // Input file incidents on the first event read from a newly opened file, so that the files
522 // seek() goes over (or opens without reading from) are not announced
524
525 // If not secondary just return the status code based on if the event is bas
526 if (!m_isSecondary.value()) {
527 // check bad event flag and handle as configured
528 return badEvent ? StatusCode::RECOVERABLE : StatusCode::SUCCESS;
529 }
530
531 // Build a DH for use by other components
532 StatusCode rec_sg = m_eventSource->generateDataHeader();
533 if (rec_sg != StatusCode::SUCCESS) {
534 ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg);
535 }
536
537 return StatusCode::SUCCESS;
538}
539//________________________________________________________________________________
540StatusCode EventSelectorByteStream::nextWithSkip(IEvtSelector::Context& ctxt) const
541{
543 return nextWithSkipImpl (ctxt, lock);
544}
545StatusCode EventSelectorByteStream::nextWithSkipImpl(IEvtSelector::Context& ctxt,
546 lock_t& lock) const {
547 ATH_MSG_DEBUG("EventSelectorByteStream::nextWithSkip");
548
549 for (;;) {
550 // Check if we're at the end of file
551 StatusCode sc = nextHandleFileTransitionImpl(ctxt, lock);
552 if (sc.isRecoverable()) {
553 continue; // handles empty files
554 }
555 if (sc.isFailure()) {
556 return StatusCode::FAILURE;
557 }
558
559 // Increase event count
560 ++m_NumEvents;
561
562 if (!m_counterTool.empty() && !m_counterTool->preNext().isSuccess()) {
563 ATH_MSG_WARNING("Failed to preNext() CounterTool.");
564 }
565 if ( m_NumEvents > m_skipEvents.value() &&
566 (m_skipEventSequence.empty() || m_NumEvents != m_skipEventSequence.front()) ) {
567 return StatusCode::SUCCESS;
568 } else {
569 if (!m_skipEventSequence.empty() && m_NumEvents == m_skipEventSequence.front()) {
570 m_skipEventSequence.erase(m_skipEventSequence.begin());
571 }
572 if (m_isSecondary.value()) {
573 ATH_MSG_INFO("skipping secondary event " << m_NumEvents);
574 } else {
575 ATH_MSG_INFO("skipping event " << m_NumEvents);
576 }
577 }
578 }
579
580 return StatusCode::SUCCESS;
581}
582//________________________________________________________________________________
583StatusCode EventSelectorByteStream::previous(IEvtSelector::Context& ctxt) const
584{
586 return previousImpl (ctxt, lock);
587}
588StatusCode EventSelectorByteStream::previousImpl(IEvtSelector::Context& /*ctxt*/,
589 lock_t& /*lock*/) const {
590 ATH_MSG_DEBUG(" ... previous");
591 const RawEvent* pre = nullptr;
592 bool badEvent(false);
593 // if event source not ready from init, try next file
594 if (m_eventSource->ready()) {
595 try {
596 pre = m_eventSource->previousEvent();
597 }
598 catch (const ByteStreamExceptions::readError&) {
599 ATH_MSG_FATAL("Caught ByteStreamExceptions::readError");
600 return StatusCode::FAILURE;
601 }
602 catch (const ByteStreamExceptions::badFragment&) {
603 ATH_MSG_ERROR("badFragment encountered");
604 badEvent = true;
605 }
606 catch (const ByteStreamExceptions::badFragmentData&) {
607 ATH_MSG_ERROR("badFragment data encountered");
608 badEvent = true;
609 }
610 // Check whether a RawEvent has actually been provided
611 if (pre == 0) {
612 ATH_MSG_ERROR("No event built");
613 return StatusCode::FAILURE;
614 }
615 }
616 else {
617 ATH_MSG_FATAL("Attempt to read previous data on invalid reader");
618 return StatusCode::FAILURE;
619 }
620 // increment that an event was found
621
622 // check bad event flag and handle as configured
623 if (badEvent) {
624 ATH_MSG_ERROR("Called previous for bad event");
625 if (!m_procBadEvent) {
626 // End of file
627 return StatusCode::FAILURE;
628 }
629 ATH_MSG_WARNING("Continue with bad event");
630 }
631
632 // Build a DH for use by other components
633 StatusCode rec_sg = m_eventSource->generateDataHeader();
634 if (rec_sg != StatusCode::SUCCESS) {
635 ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg);
636 }
637
638 return StatusCode::SUCCESS;
639}
640//________________________________________________________________________________
641StatusCode EventSelectorByteStream::previous(IEvtSelector::Context& ctxt, int jump) const {
643 return previousImpl (ctxt, jump, lock);
644}
645//________________________________________________________________________________
647EventSelectorByteStream::previousImpl(IEvtSelector::Context& ctxt,
648 int jump,
649 lock_t& lock) const
650{
651 if (jump > 0) {
652 for (int i = 0; i < jump; i++) {
654 }
655 return StatusCode::SUCCESS;
656 }
657 return StatusCode::FAILURE;
658}
659//________________________________________________________________________________
660StatusCode EventSelectorByteStream::last(IEvtSelector::Context& it)const {
661 if (it.identifier() == m_endIter->identifier()) {
662 ATH_MSG_DEBUG("last(): Last event in InputStream.");
663 return StatusCode::SUCCESS;
664 }
665 return StatusCode::FAILURE;
666}
667//________________________________________________________________________________
668StatusCode EventSelectorByteStream::rewind(IEvtSelector::Context& /*it*/) const {
669 ATH_MSG_ERROR("rewind() not implemented");
670 return StatusCode::FAILURE;
671}
672
673//________________________________________________________________________________
674StatusCode EventSelectorByteStream::resetCriteria(const std::string& /*criteria*/, IEvtSelector::Context& /*ctxt*/) const {
675 return StatusCode::SUCCESS;
676}
677
678//__________________________________________________________________________
679StatusCode EventSelectorByteStream::seek(Context& /* it */, int evtNum) const {
681 // Check that input is seekable
682 if (!m_filebased) {
683 ATH_MSG_ERROR("Input not seekable, choose different input svc");
684 return StatusCode::FAILURE;
685 }
686 // find the file index with that event
687 long fileNum = findEvent(evtNum, lock);
688 if (fileNum == -1 && evtNum >= m_firstEvt[m_fileCount] && evtNum < m_NumEvents) {
689 fileNum = m_fileCount;
690 }
691 // if unable to locate file, exit
692 if (fileNum == -1) {
693 ATH_MSG_INFO("seek: Reached end of Input.");
694 return StatusCode::RECOVERABLE;
695 }
696 // check if it is the current file
697 if (fileNum != m_fileCount) { // event in different file
698 // Close input file if open
699 if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true);
700 ATH_MSG_DEBUG("Seek to item: \"" << m_inputCollectionsProp.value()[fileNum] << "\" from the explicit file list.");
701 std::string fileName = m_inputCollectionsProp.value()[fileNum];
702 m_fileCount = fileNum;
703 m_inputCollectionsIterator = m_inputCollectionsProp.value().begin() + fileNum;
704 // Open the correct file; next() fires its input file incidents when it reads from it
705 if (openBlock(fileName, lock) == -1) {
706 ATH_MSG_FATAL("Unable to open file with seeked event " << evtNum << " file " << fileName);
707 return StatusCode::FAILURE;
708 }
709 int delta = evtNum - m_firstEvt[m_fileCount];
710 if (delta > 0) {
712 ATH_CHECK(nextImpl(*beginIter,delta, lock));
713 }
714 }
715 // event in current file
716 {
717 int delta = (evtNum - m_firstEvt[m_fileCount] + 1) - m_eventSource->positionInBlock();
718 ATH_MSG_DEBUG("Seeking event " << evtNum << " in current file with delta " << delta);
719 if ( delta == 0 ) { // current event
720 // nothing to do
721 }
722 else if ( delta > 0 ) { // forward
724 ATH_CHECK(this->nextImpl(*beginIter, delta, lock));
725 }
726 else if ( delta < 0 ) { // backward
728 ATH_CHECK(this->previousImpl(*beginIter, -1*delta, lock));
729 }
730 }
731 return StatusCode::SUCCESS;
732}
733
740{
741 std::string listName("EventInfoAtts");
742
743 if (eventStore()->contains<AthenaAttributeList>(listName)) {
744 const AthenaAttributeList* oldAttrList = nullptr;
745 ATH_CHECK(eventStore()->retrieve(oldAttrList, listName));
746 ATH_CHECK(eventStore()->removeDataAndProxy(oldAttrList));
747 }
748
749 // build the new attr list
750 auto attrList = std::make_unique<AthenaAttributeList>();
751
752 // fill the attr list
753 ATH_CHECK(fillAttributeListImpl(attrList.get(), "", false, lock));
754
755 // put result in event store
756 ATH_CHECK(eventStore()->record(std::move(attrList), listName));
757
758 return StatusCode::SUCCESS;
759}
760
761StatusCode EventSelectorByteStream::fillAttributeList(coral::AttributeList *attrList, const std::string &suffix, bool copySource) const
762{
764 return fillAttributeListImpl (attrList, suffix, copySource, lock);
765}
766StatusCode EventSelectorByteStream::fillAttributeListImpl(coral::AttributeList *attrList, const std::string &suffix, bool /* copySource */,
767 lock_t& /*lock*/) const
768{
769 attrList->extend("RunNumber" + suffix, "unsigned int");
770 attrList->extend("EventNumber" + suffix, "unsigned long long");
771 attrList->extend("LumiBlockN" + suffix, "unsigned int");
772 attrList->extend("BunchId" + suffix, "unsigned int");
773 attrList->extend("EventTime" + suffix, "unsigned int");
774 attrList->extend("EventTimeNanoSec" + suffix, "unsigned int");
775
776 // fill attribute list
777 const RawEvent* event = m_eventSource->currentEvent();
778
779 (*attrList)["RunNumber" + suffix].data<unsigned int>() = event->run_no();
780 if (event->version() < 0x03010000) {
781 (*attrList)["EventNumber" + suffix].data<unsigned long long>() = event->lvl1_id();
782 } else {
783 (*attrList)["EventNumber" + suffix].data<unsigned long long>() = event->global_id();
784 }
785 (*attrList)["LumiBlockN" + suffix].data<unsigned int>() = event->lumi_block();
786 (*attrList)["BunchId" + suffix].data<unsigned int>() = event->bc_id();
787
788 unsigned int bc_time_sec = event->bc_time_seconds();
789 unsigned int bc_time_ns = event->bc_time_nanoseconds();
790 // bc_time_ns should be lt 1e9.
791 if (bc_time_ns > 1000000000) {
792 // round it off to 1e9
793 ATH_MSG_WARNING(" bc_time nanosecond number larger than 1e9, it is " << bc_time_ns << ", reset it to 1 sec");
794 bc_time_ns = 1000000000;
795 }
796 (*attrList)["EventTime" + suffix].data<unsigned int>() = bc_time_sec;
797 (*attrList)["EventTimeNanoSec" + suffix].data<unsigned int>() = bc_time_ns;
798
800
801 event->status(buffer);
802 attrList->extend("TriggerStatus" + suffix, "unsigned int");
803 (*attrList)["TriggerStatus" + suffix].data<unsigned int>() = *buffer;
804
805 attrList->extend("ExtendedL1ID" + suffix, "unsigned int");
806 attrList->extend("L1TriggerType" + suffix, "unsigned int");
807 (*attrList)["ExtendedL1ID" + suffix].data<unsigned int>() = event->lvl1_id();
808 (*attrList)["L1TriggerType" + suffix].data<unsigned int>() = event->lvl1_trigger_type();
809
810 // Grab L1 words
811 event->lvl1_trigger_info(buffer);
812 for (uint32_t iT1 = 0; iT1 < event->nlvl1_trigger_info(); ++iT1) {
813 std::stringstream name;
814 name << "L1TriggerInfo_" << iT1;
815 attrList->extend(name.str() + suffix, "unsigned int");
816 (*attrList)[name.str() + suffix].data<unsigned int>() = *buffer;
817 ++buffer;
818 }
819
820 // Grab L2 words
821 event->lvl2_trigger_info(buffer);
822 for (uint32_t iT1 = 0; iT1 < event->nlvl2_trigger_info(); ++iT1) {
823 if (*buffer != 0) {
824 std::stringstream name;
825 name << "L2TriggerInfo_" << iT1;
826 attrList->extend(name.str() + suffix, "unsigned int");
827 (*attrList)[name.str() + suffix].data<unsigned int>() = *buffer;
828 }
829 ++buffer;
830 }
831
832 // Grab EF words
833 event->event_filter_info(buffer);
834 for (uint32_t iT1 = 0; iT1 < event->nevent_filter_info(); ++iT1) {
835 if (*buffer != 0) {
836 std::stringstream name;
837 name << "EFTriggerInfo_" << iT1;
838 attrList->extend(name.str() + suffix, "unsigned int");
839 (*attrList)[name.str() + suffix].data<unsigned int>() = *buffer;
840 }
841 ++buffer;
842 }
843
844 // Grab stream tags
845 event->stream_tag(buffer);
846 std::vector<eformat::helper::StreamTag> onl_streamTags;
847 eformat::helper::decode(event->nstream_tag(), buffer, onl_streamTags);
848 for (std::vector<eformat::helper::StreamTag>::const_iterator itS = onl_streamTags.begin(),
849 itSE = onl_streamTags.end(); itS != itSE; ++itS) {
850 attrList->extend(itS->name + suffix, stringTypeStr);
851 (*attrList)[itS->name + suffix].data<std::string>() = itS->type;
852 }
853
854 return StatusCode::SUCCESS;
855}
856
857//__________________________________________________________________________
858int EventSelectorByteStream::findEvent(int evtNum, lock_t& /*lock*/) const {
859 // Loop over file event counts
860 for (size_t i = 0; i < m_inputCollectionsProp.value().size(); i++) {
861 if (m_inputCollectionsProp.value().size() != m_numEvt.size()) {
862 ATH_MSG_ERROR("vector size incompatibility");
863 break;
864 }
865 // if file not opened yet, check it
866 if (m_numEvt[i] == -1) {
867 std::string fileName = m_inputCollectionsProp.value()[i];
868 // only to count its events, so not openBlock(): it must not become the current file
869 auto nevguid = m_eventSource->getBlockIterator(fileName);
870 long nev = nevguid.first;
871 // if failure on file open, exit
872 if (nev==-1) {
873 break;
874 }
875 // set initial event counter for that file
876 if (i > 0) {
877 m_firstEvt[i] = m_firstEvt[i - 1] + m_numEvt[i - 1];
878 } else {
879 m_firstEvt[i] = 0;
880 }
881 // log number of events in that file
882 m_numEvt[i] = nev;
883 }
884 // if sought event is in this file, then return the index of that file
885 if (evtNum >= m_firstEvt[i] && evtNum < m_firstEvt[i] + m_numEvt[i]) {
886 ATH_MSG_INFO("found " << evtNum << " in file " << i);
887 return i;
888 }
889 }
890 ATH_MSG_INFO("did not find ev " << evtNum);
891 // return file not found marker
892 return -1;
893}
894
895//__________________________________________________________________________
896int EventSelectorByteStream::curEvent (const Context& /*it*/) const {
897 // event counter in IEvtSelectorSeek interface
899 return int(m_NumEvents);
900}
901
902//__________________________________________________________________________
903int EventSelectorByteStream::size (Context& /*it*/) const {
904 return -1;
905}
906
907//________________________________________________________________________________
908StatusCode EventSelectorByteStream::makeServer(int /*num*/) {
910 if (m_eventStreamingTool.empty()) {
911 return StatusCode::FAILURE;
912 }
913 return m_eventStreamingTool->makeServer(1, "");
914}
915
916//________________________________________________________________________________
917StatusCode EventSelectorByteStream::makeClient(int /*num*/) {
919 if (m_eventStreamingTool.empty()) {
920 return StatusCode::FAILURE;
921 }
922 std::string dummyStr;
923 return m_eventStreamingTool->makeClient(0, dummyStr);
924}
925
926//________________________________________________________________________________
927StatusCode EventSelectorByteStream::share(int evtNum) {
929 if (m_eventStreamingTool.empty()) {
930 return StatusCode::FAILURE;
931 }
932 if (m_eventStreamingTool->isClient()) {
933 StatusCode sc = m_eventStreamingTool->lockEvent(evtNum);
934 while (sc.isRecoverable()) {
935 usleep(1000);
936 sc = m_eventStreamingTool->lockEvent(evtNum);
937 }
938 return sc;
939 }
940 return StatusCode::FAILURE;
941}
942
943//________________________________________________________________________________
946 if (m_eventStreamingTool.empty()) {
947 ATH_MSG_ERROR("No AthenaSharedMemoryTool configured for readEvent()");
948 return StatusCode::FAILURE;
949 }
950 ATH_MSG_VERBOSE("Called read Event " << maxevt);
951 for (int i = 0; i < maxevt || maxevt == -1; ++i) {
952 const RawEvent* pre = nullptr;
953 if (this->nextImpl(*m_beginIter, lock).isSuccess()) {
954 pre = m_eventSource->currentEvent();
955 } else {
956 if (m_NumEvents == -1) {
957 ATH_MSG_VERBOSE("Called read Event and read last event from input: " << i);
958 break;
959 }
960 ATH_MSG_ERROR("Unable to retrieve next event for " << i << "/" << maxevt);
961 return StatusCode::FAILURE;
962 }
963 if (m_eventStreamingTool->isServer()) {
964 StatusCode sc;
965 while ( (sc = putEvent_ST(*m_eventStreamingTool,
966 m_NumEvents - 1,
967 pre->start(),
968 pre->fragment_size_word() * sizeof(uint32_t),
969 m_eventSource->currentEventStatus())).isRecoverable() ) {
970 usleep(1000);
971 }
972 ATH_CHECK(sc);
973 }
974 }
975 // End of file, wait for last event to be taken
976 StatusCode sc;
977 while ( (sc = putEvent_ST(*m_eventStreamingTool, 0, 0, 0, 0)).isRecoverable() ) {
978 usleep(1000);
979 }
980 ATH_CHECK(sc);
981 return StatusCode::SUCCESS;
982}
983
984//________________________________________________________________________________
985StatusCode EventSelectorByteStream::createAddress(const IEvtSelector::Context& /*it*/,
986 IOpaqueAddress*& iop) const {
987 SG::DataProxy* proxy = eventStore()->proxy(ClassID_traits<DataHeader>::ID(),"ByteStreamDataHeader");
988 if (proxy !=0) {
989 iop = proxy->address();
990 return StatusCode::SUCCESS;
991 } else {
992 iop = 0;
993 return StatusCode::FAILURE;
994 }
995}
996
997//________________________________________________________________________________
998StatusCode
999EventSelectorByteStream::releaseContext(IEvtSelector::Context*& /*it*/) const {
1000 return StatusCode::SUCCESS;
1001}
1002
1003//________________________________________________________________________________
1006 ATH_MSG_INFO("I/O reinitialization...");
1007 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
1008 ATH_CHECK(iomgr.retrieve());
1009 if (!iomgr->io_hasitem(this)) {
1010 ATH_MSG_FATAL("IoComponentMgr does not know about myself !");
1011 return StatusCode::FAILURE;
1012 }
1013 std::vector<std::string> inputCollections = m_inputCollectionsProp.value();
1014 for (std::size_t i = 0, imax = inputCollections.size(); i != imax; ++i) {
1015 ATH_MSG_INFO("I/O reinitialization, file = " << inputCollections[i]);
1016 std::string &fname = inputCollections[i];
1017 if (!iomgr->io_contains(this, fname)) {
1018 ATH_MSG_ERROR("IoComponentMgr does not know about [" << fname << "] !");
1019 return StatusCode::FAILURE;
1020 }
1021 ATH_CHECK(iomgr->io_retrieve(this, fname));
1022 }
1023 // all good... copy over.
1024 m_inputFileGuard.reset();
1025 m_pendingFile.reset();
1026
1027 // Set m_inputCollectionsProp. But we _dont_ want to run the update
1028 // handler --- that calls reinit(), which will deadlock since
1029 // we're holding the lock. Instead, we'll call reinit() ourselves.
1030 auto old_cb = m_inputCollectionsProp.updateCallBack();
1031 m_inputCollectionsProp.declareUpdateHandler(
1032 [] (Gaudi::Details::PropertyBase&) {}
1033 );
1034 m_inputCollectionsProp = inputCollections;
1035 m_inputCollectionsProp.declareUpdateHandler (std::move(old_cb));
1036
1037 return this->reinit(lock);
1038}
1039
1040//__________________________________________________________________________
1042{
1043 return true;
1044}
#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 DataHeader and DataHeaderElement classes.
This file contains the class definition for the EventContextByteStream class.
This file contains the class definition for the IAthMetaDataSvc class.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
RAII guard that guarantees a matching end-incident for every begin-incident.
static Double_t sc
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition RawEvent.h:37
size_t size() const
Number of registered mappings.
int imax(int i, int j)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
An AttributeList represents a logical row of attributes in a metadata table.
This class provides the Context for EventSelectorByteStream.
virtual StatusCode initialize() override
Implementation of Service base class methods.
virtual StatusCode stop() override
Gaudi::Property< bool > m_isSecondary
IsSecondary, know if this is an instance of secondary event selector.
virtual int size(Context &it) const override
Always returns -1.
void fileTransition(lock_t &lock) const
EndInputFile for the file begun last and BeginInputFile for the file opened since,...
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.
Gaudi::Property< std::string > m_eventSourceName
ToolHandle< IAthenaSelectorTool > m_counterTool
virtual StatusCode share(int evtnum) override
Request to share a given event number.
Gaudi::Property< bool > m_filebased
virtual StatusCode resetCriteria(const std::string &criteria, Context &context) const override
Set a selection criteria.
std::lock_guard< mutex_t > lock_t
SmartIF< IByteStreamInputSvc > m_eventSource
Gaudi::CheckedProperty< uint32_t > m_firstLBNo
virtual StatusCode readEvent(int maxevt) override
Read the next maxevt events.
EventContextByteStream * m_endIter
int findEvent(int evtNum, lock_t &lock) const
Search for event with number evtNum.
virtual StatusCode releaseContext(Context *&it) const override
virtual StatusCode makeServer(int num) override
Make this a server.
virtual bool disconnectIfFinished(const SG::SourceID &fid) const override
Gaudi::CheckedProperty< uint64_t > m_eventsPerRun
virtual StatusCode nextWithSkip(IEvtSelector::Context &ctxt) const override
Go to next event and skip if necessary.
ToolHandleArray< IAthenaSelectorTool > m_helperTools
HelperTools, vector of names of AlgTools that are executed by the EventSelector.
virtual StatusCode finalize() override
StatusCode previousImpl(Context &it, lock_t &lock) const
virtual StatusCode last(Context &it) const override
long openBlock(const std::string &fileName, lock_t &lock) const
Open fileName as the current file, without input file incidents (see fileTransition()).
Gaudi::CheckedProperty< uint32_t > m_initTimeStamp
Gaudi::CheckedProperty< uint32_t > m_eventsPerLB
Gaudi::Property< bool > m_procBadEvent
process bad events, which fail check_tree().
Gaudi::CheckedProperty< uint32_t > m_runNo
virtual StatusCode createContext(Context *&it) const override
create context
virtual StatusCode createAddress(const Context &it, IOpaqueAddress *&iop) const override
virtual StatusCode makeClient(int num) override
Make this a client.
virtual int curEvent(const Context &it) const override
Return the current event number.
ServiceHandle< IIncidentSvc > m_incidentSvc
StatusCode nextImpl(Context &it, lock_t &lock) const
StatusCode fillAttributeListImpl(coral::AttributeList *attrList, const std::string &suffix, bool copySource, lock_t &lock) const
void nextFile(lock_t &lock) const
StatusCode nextHandleFileTransitionImpl(IEvtSelector::Context &ctxt, lock_t &lock) const
virtual StatusCode rewind(Context &it) const override
StatusCode reinit(lock_t &lock)
Reinitialize the service when a fork() occurred/was-issued.
Gaudi::Property< std::vector< std::string > > m_inputCollectionsProp
virtual StatusCode next(Context &it) const override
int m_fileCount ATLAS_THREAD_SAFE
number of files to process.
StatusCode openNewRun(lock_t &lock) const
virtual StatusCode io_reinit() override
Callback method to reinitialize the internal state of the component for I/O purposes (e....
virtual ~EventSelectorByteStream()
Standard Destructor.
Gaudi::Property< std::vector< long > > m_skipEventSequenceProp
StoreGateSvc * eventStore() const
void inputCollectionsHandler(Gaudi::Details::PropertyBase &)
virtual StatusCode start() override
virtual StatusCode recordAttributeList() const override
Record AttributeList in StoreGate.
virtual StatusCode seek(Context &, int evtnum) const override
Seek to a given event number.
StatusCode nextWithSkipImpl(IEvtSelector::Context &ctxt, lock_t &lock) const
StatusCode recordAttributeListImpl(lock_t &lock) const
Gaudi::CheckedProperty< uint64_t > m_firstEventNo
EventContextByteStream * m_beginIter
virtual StatusCode nextHandleFileTransition(IEvtSelector::Context &ctxt) const override
Handle file transition at the next iteration.
Gaudi::Property< long > m_skipEvents
virtual StatusCode previous(Context &it) const override
Gaudi::Property< int > m_maxBadEvts
number of bad events allowed before quitting.
EventSelectorByteStream(const std::string &name, ISvcLocator *svcloc)
Standard Constructor.
static void transition(std::optional< InputFileIncidentGuard > &guard, IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Replace the guard in an optional, with strict End-before-Begin ordering.
The Athena Transient Store API.
static StoreGateSvc * currentStoreGate()
get current StoreGate
virtual SG::DataProxy * proxy(const void *const pTransient) const override final
get proxy for a given data object address in memory
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
::StatusCode StatusCode
StatusCode definition for legacy code.
status
Definition merge.py:16
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.