13#include "GaudiKernel/IIncidentSvc.h"
14#include "GaudiKernel/FileIncident.h"
15#include "GaudiKernel/ConcurrencyFlags.h"
26 : base_class(name, pSvcLocator),
41 if (!incsvc.retrieve().isSuccess()) {
43 return(StatusCode::FAILURE);
47 incsvc->addListener(
this, IncidentType::BeginProcessing, 100);
53 return StatusCode::FAILURE;
65 return(StatusCode::SUCCESS);
73 return(StatusCode::SUCCESS);
78 return Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents() > 1;
83 std::lock_guard lockg(
m_mutex );
90 const EventContext& ctx = inc.context();
96 const FileIncident* fileInc =
dynamic_cast<const FileIncident*
>(&inc);
97 if (fileInc !=
nullptr) {
98 rangeID = fileInc->fileName();
100 if (inc.type() == IncidentType::BeginInputFile) {
104 "Requested (through incident) Next Event Range filename extension: {}",
108 if( rangeID ==
"dummy" ) {
114 bool disconnect {
true };
115 std::lock_guard lockg(
m_mutex );
117 throw GaudiException(
"Cannot transition MetaData", name(), StatusCode::FAILURE);
125 std::lock_guard lockg(
m_mutex );
127 if( rangeID.empty() ) {
128 std::ostringstream n;
131 ATH_MSG_DEBUG(
"Default next event range filename extension: {}", rangeID);
133 else if (rangeID ==
"INFILE") {
146 bool disconnect {
false };
148 if( !
m_metaDataSvc->transitionMetaDataFile(
"" , disconnect ).isSuccess() ) {
149 throw GaudiException(
"Cannot transition MetaData", name(), StatusCode::FAILURE);
153 else if( inc.type() == IncidentType::BeginProcessing ) {
155 std::lock_guard lockg(
m_mutex );
170 std::lock_guard lockg(
m_mutex );
173 std::string fileNameCore = orgFileName, fileNameExt;
174 std::size_t sepPos = orgFileName.find(
'[');
175 if (sepPos != std::string::npos) {
176 fileNameCore = orgFileName.substr(0, sepPos);
177 fileNameExt = orgFileName.substr(sepPos);
181 std::string_view origFileNameView = orgFileName;
182 std::size_t open = origFileNameView.find(
'[');
183 std::size_t close = origFileNameView.find(
']');
186 if (open == std::string_view::npos || close == std::string_view::npos) {
191 std::vector<std::string_view> elems{};
192 std::size_t pos = open + 1;
193 for (std::size_t comma = origFileNameView.find(
',', pos);
195 comma = origFileNameView.find(
',', pos)) {
196 std::string_view item = origFileNameView.substr(pos, comma - pos);
197 ATH_MSG_DEBUG(
"(start) pos = {}, (end) comma = comma, item = {}",
199 elems.push_back(item);
202 std::string_view last_item = origFileNameView.substr(pos, close - pos);
203 ATH_MSG_DEBUG(
"(start) pos = {}, (end) close = {}, item = {}",
204 pos, close, last_item);
205 elems.push_back(last_item);
207 std::size_t rangeIdx{};
208 auto rangeIdxParseRes = std::from_chars(
209 rangeID.data(), rangeID.data() + rangeID.size(), rangeIdx);
210 if (rangeIdxParseRes.ec != std::errc()) {
212 "Error parsing rangeID to integer. Replacing [] list with "
215 std::format(
"{}{}{}", origFileNameView.substr(0, open), rangeID,
216 origFileNameView.substr(close + 1));
217 }
else if (rangeIdx >= elems.size()) {
219 "Number of elements in [] list <= rangeID. Replacing [] list with "
222 std::format(
"{}{}{}", origFileNameView.substr(0, open), rangeID,
223 origFileNameView.substr(close + 1));
226 "{}{}{}", origFileNameView.substr(0, open), elems.at(rangeIdx),
227 origFileNameView.substr(close + 1));
243 if( !
inUse() )
return "";
251 const std::string oldrange = *rangeid;
259 std::lock_guard lockg(
m_mutex );
270 std::lock_guard lockg(
m_mutex );
#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 OutputStreamSequencerSvc class.
static const Attributes_t empty
void publishRangeReport(const std::string &outputFile)
SG::SlotSpecificObj< std::string, SG::InvalidSlot::Enabled > m_rangeIDinSlot
EventRange ID for all slots.
bool inUse() const
Is the service in active use? (true after the first range incident is handled).
OutputStreamSequencerSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard Service Constructor.
std::string buildSequenceFileName(const EventContext &ctx, const std::string &)
Returns sequenced file name for output stream.
virtual void handle(const Incident &) override final
Incident service handle.
RangeReport_ptr getRangeReport()
std::string m_lastFileName
Recently constructed full file name (useful in single threaded processing).
std::string currentRangeID(const EventContext &ctx) const
The current Event Range ID (only one range is returned).
ServiceHandle< MetaDataSvc > m_metaDataSvc
int m_fileSequenceNumber
The event sequence number.
BooleanProperty m_replaceRangeMode
Flag to put in ReplaceRangeMode (i.e.
virtual StatusCode finalize() override final
Required of all Gaudi services:
std::string incidentName() const
The name of the incident that starts a new event sequence.
std::string m_currentRangeID
Current EventRange ID constructed on the last NextRange incident.
virtual ~OutputStreamSequencerSvc()
Destructor.
BooleanProperty m_reportingOn
Flag to switch on storage of reporting info in fnToRangeId.
static bool inConcurrentEventsMode()
Are there concurrent events? (threads>1).
std::string m_lastIncident
Last incident type that was handled.
std::string setRangeID(const EventContext &ctx, const std::string &rangeID)
set the RangeID (possibly temporarily) so the right Range Filename may be generated
std::unique_ptr< RangeReport_t > RangeReport_ptr
std::map< std::string, std::string >::iterator m_finishedRange
virtual StatusCode initialize() override final
Required of all Gaudi services:
std::map< std::string, std::string > m_fnToRangeId