Skip to content
Snippets Groups Projects
Commit 8b860e2c authored by Rafal Bielski's avatar Rafal Bielski :wave:
Browse files

TrigByteStreamCnvSvc: Change inheritance and implement explicit EventContext passing

* Derive TrigByteStreamCnvSvc from ByteStreamCnvSvcBase instead of ByteStreamCnvSvc.
* Implement explicit EventContext passing through all methods which need it. Make the interface implementation methods retrieve the EventContext and call the context-aware local methods.
parent 507ac800
No related branches found
No related tags found
No related merge requests found
...@@ -11,13 +11,9 @@ ...@@ -11,13 +11,9 @@
#include "ByteStreamData/RawEvent.h" #include "ByteStreamData/RawEvent.h"
/** /**
@class ByteStreamCnvSvcBase * @class ByteStreamCnvSvcBase
@brief base class for ByteStream conversion service. * @brief The base class for offline and HLT ByteStream conversion services
*/
description
This class is used as a conversion service in online HLT
and it is the base class for offline bytestream conversion service.
*/
class ByteStreamCnvSvcBase : public ::AthCnvSvc, class ByteStreamCnvSvcBase : public ::AthCnvSvc,
public virtual IIncidentListener, public virtual IIncidentListener,
public virtual IByteStreamEventAccess { public virtual IByteStreamEventAccess {
......
...@@ -84,7 +84,7 @@ namespace { ...@@ -84,7 +84,7 @@ namespace {
// Standard constructor // Standard constructor
// ============================================================================= // =============================================================================
TrigByteStreamCnvSvc::TrigByteStreamCnvSvc(const std::string& name, ISvcLocator* svcLoc) TrigByteStreamCnvSvc::TrigByteStreamCnvSvc(const std::string& name, ISvcLocator* svcLoc)
: ByteStreamCnvSvc(name, svcLoc) {} : ByteStreamCnvSvcBase(name, svcLoc) {}
// ============================================================================= // =============================================================================
// Standard destructor // Standard destructor
...@@ -96,7 +96,7 @@ TrigByteStreamCnvSvc::~TrigByteStreamCnvSvc() {} ...@@ -96,7 +96,7 @@ TrigByteStreamCnvSvc::~TrigByteStreamCnvSvc() {}
// ============================================================================= // =============================================================================
StatusCode TrigByteStreamCnvSvc::initialize() { StatusCode TrigByteStreamCnvSvc::initialize() {
ATH_MSG_VERBOSE("start of " << __FUNCTION__); ATH_MSG_VERBOSE("start of " << __FUNCTION__);
ATH_CHECK(ByteStreamCnvSvc::initialize()); ATH_CHECK(ByteStreamCnvSvcBase::initialize());
ATH_CHECK(m_evtStore.retrieve()); ATH_CHECK(m_evtStore.retrieve());
ATH_CHECK(m_robDataProviderSvc.retrieve()); ATH_CHECK(m_robDataProviderSvc.retrieve());
if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve()); if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
...@@ -114,7 +114,7 @@ StatusCode TrigByteStreamCnvSvc::finalize() { ...@@ -114,7 +114,7 @@ StatusCode TrigByteStreamCnvSvc::finalize() {
if (m_evtStore.release().isFailure()) if (m_evtStore.release().isFailure())
ATH_MSG_WARNING("Failed to release service " << m_evtStore.typeAndName()); ATH_MSG_WARNING("Failed to release service " << m_evtStore.typeAndName());
ATH_MSG_VERBOSE("end of " << __FUNCTION__); ATH_MSG_VERBOSE("end of " << __FUNCTION__);
ATH_CHECK(ByteStreamCnvSvc::finalize()); ATH_CHECK(ByteStreamCnvSvcBase::finalize());
return StatusCode::SUCCESS; return StatusCode::SUCCESS;
} }
...@@ -122,22 +122,19 @@ StatusCode TrigByteStreamCnvSvc::finalize() { ...@@ -122,22 +122,19 @@ StatusCode TrigByteStreamCnvSvc::finalize() {
// Implementation of IConversionSvc::connectOutput // Implementation of IConversionSvc::connectOutput
// The argument outputFile is not used // The argument outputFile is not used
// ============================================================================= // =============================================================================
StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& /*outputFile*/) { StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& outputFile) {
ATH_MSG_VERBOSE("start of " << __FUNCTION__); const EventContext* eventContext = currentContext();
if (eventContext == nullptr) return StatusCode::FAILURE;
return connectOutput(outputFile, *eventContext);
}
// Get the EventContext via event store because the interface doesn't allow passing it explicitly as an argument StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& /*outputFile*/, const EventContext& eventContext) {
// and we don't want to use ThreadLocalContext. Don't use ReadHandle here because it calls ThreadLocalContext if ATH_MSG_VERBOSE("start of " << __FUNCTION__);
// not given a context (which we want to retrieve).
const EventContext* eventContext = nullptr;
if (m_evtStore->retrieve(eventContext).isFailure()) {
ATH_MSG_ERROR("Failed to retrieve EventContext from the event store");
return StatusCode::FAILURE;
}
ATH_MSG_DEBUG("Creating new RawEventWrite for EventContext = " << *eventContext); ATH_MSG_DEBUG("Creating new RawEventWrite for EventContext = " << eventContext);
// Create a new RawEventWrite and copy the header from the input RawEvent // Create a new RawEventWrite and copy the header from the input RawEvent
RawEventWrite* re = setRawEvent (std::make_unique<RawEventWrite>()); RawEventWrite* re = setRawEvent(std::make_unique<RawEventWrite>(), eventContext);
const uint32_t* inputRawEvent = m_robDataProviderSvc->getEvent(*eventContext)->start(); const uint32_t* inputRawEvent = m_robDataProviderSvc->getEvent(eventContext)->start();
if (!inputRawEvent) { if (!inputRawEvent) {
ATH_MSG_ERROR("Input RawEvent is nullptr, cannot create output"); ATH_MSG_ERROR("Input RawEvent is nullptr, cannot create output");
return StatusCode::FAILURE; return StatusCode::FAILURE;
...@@ -163,12 +160,18 @@ StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& outputFile, co ...@@ -163,12 +160,18 @@ StatusCode TrigByteStreamCnvSvc::connectOutput(const std::string& outputFile, co
// The arguments outputFile and do_commit are not used // The arguments outputFile and do_commit are not used
// NOTE: In online HLT, m_rawEventWrite is not a full event, it contains only the HLTResult ROBFragments // NOTE: In online HLT, m_rawEventWrite is not a full event, it contains only the HLTResult ROBFragments
// ============================================================================= // =============================================================================
StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/, bool /*do_commit*/) { StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& outputFile, bool do_commit) {
const EventContext* eventContext = currentContext();
if (eventContext == nullptr) return StatusCode::FAILURE;
return commitOutput(outputFile, do_commit, *eventContext);
}
StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/, bool /*do_commit*/, const EventContext& eventContext) {
ATH_MSG_VERBOSE("start of " << __FUNCTION__); ATH_MSG_VERBOSE("start of " << __FUNCTION__);
if (msgLvl(MSG::DEBUG)) printRawEvent(); if (msgLvl(MSG::DEBUG)) printRawEvent(eventContext);
RawEventWrite* re = getRawEvent(); RawEventWrite* re = getRawEvent(eventContext);
// Serialise the output FullEventFragment // Serialise the output FullEventFragment
std::unique_ptr<uint32_t[]> rawEventPtr; std::unique_ptr<uint32_t[]> rawEventPtr;
...@@ -184,10 +187,12 @@ StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/, ...@@ -184,10 +187,12 @@ StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/,
} }
catch (const std::exception& e) { catch (const std::exception& e) {
ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected std::exception " << e.what()); ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected std::exception " << e.what());
clearRawEvent(eventContext);
return StatusCode::FAILURE; return StatusCode::FAILURE;
} }
catch (...) { catch (...) {
ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected exception"); ATH_MSG_ERROR("FullEventFragment serialisation failed, caught an unexpected exception");
clearRawEvent(eventContext);
return StatusCode::FAILURE; return StatusCode::FAILURE;
} }
...@@ -215,12 +220,48 @@ StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/, ...@@ -215,12 +220,48 @@ StatusCode TrigByteStreamCnvSvc::commitOutput(const std::string& /*outputFile*/,
result = StatusCode::FAILURE; result = StatusCode::FAILURE;
} }
setRawEvent (std::unique_ptr<RawEventWrite>()); clearRawEvent(eventContext);
ATH_MSG_VERBOSE("end of " << __FUNCTION__); ATH_MSG_VERBOSE("end of " << __FUNCTION__);
return result; return result;
} }
// =============================================================================
const EventContext* TrigByteStreamCnvSvc::currentContext() const {
// Get the EventContext via event store because the base class doesn't allow passing it explicitly as an argument
// and we don't want to use ThreadLocalContext. Don't use ReadHandle here because it calls ThreadLocalContext if
// not given a context (which we want to retrieve). This relies on IHiveWhiteBoard::selectStore being called on the
// current thread before we arrive here (it is done in HltEventLoopMgr).
const EventContext* eventContext = nullptr;
if (m_evtStore->retrieve(eventContext).isFailure()) {
ATH_MSG_ERROR("Failed to retrieve EventContext from the event store");
}
return eventContext;
}
// =============================================================================
RawEventWrite* TrigByteStreamCnvSvc::getRawEvent() {
const EventContext* eventContext = currentContext();
if (eventContext == nullptr) return nullptr;
return getRawEvent(*eventContext);
}
// =============================================================================
RawEventWrite* TrigByteStreamCnvSvc::getRawEvent(const EventContext& eventContext) const {
return m_rawEventWriteCache.get(eventContext)->get();
}
// =============================================================================
RawEventWrite* TrigByteStreamCnvSvc::setRawEvent(std::unique_ptr<RawEventWrite>&& rawEventWrite, const EventContext& eventContext) {
*(m_rawEventWriteCache.get(eventContext)) = std::move(rawEventWrite);
return getRawEvent(eventContext);
}
// =============================================================================
void TrigByteStreamCnvSvc::clearRawEvent(const EventContext& eventContext) {
m_rawEventWriteCache.get(eventContext)->reset();
}
// ============================================================================= // =============================================================================
void TrigByteStreamCnvSvc::monitorRawEvent(const std::unique_ptr<uint32_t[]>& rawEventPtr) const { void TrigByteStreamCnvSvc::monitorRawEvent(const std::unique_ptr<uint32_t[]>& rawEventPtr) const {
// Create a read fragment from the pointer // Create a read fragment from the pointer
...@@ -346,8 +387,8 @@ void TrigByteStreamCnvSvc::monitorRawEvent(const std::unique_ptr<uint32_t[]>& ra ...@@ -346,8 +387,8 @@ void TrigByteStreamCnvSvc::monitorRawEvent(const std::unique_ptr<uint32_t[]>& ra
} }
// ============================================================================= // =============================================================================
void TrigByteStreamCnvSvc::printRawEvent() { void TrigByteStreamCnvSvc::printRawEvent(const EventContext& eventContext) const {
RawEventWrite* re = getRawEvent(); RawEventWrite* re = getRawEvent(eventContext);
if (!re) { if (!re) {
ATH_MSG_WARNING("RawEventWrite pointer is null"); ATH_MSG_WARNING("RawEventWrite pointer is null");
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
#ifndef TRIGBYTESTREAMCNVSVC_H #ifndef TRIGBYTESTREAMCNVSVC_H
#define TRIGBYTESTREAMCNVSVC_H #define TRIGBYTESTREAMCNVSVC_H
#include "ByteStreamCnvSvc/ByteStreamCnvSvc.h" #include "ByteStreamCnvSvcBase/ByteStreamCnvSvcBase.h"
#include "AthenaMonitoringKernel/Monitored.h" #include "AthenaMonitoringKernel/Monitored.h"
#include "AthenaKernel/SlotSpecificObj.h"
// Forward declarations // Forward declarations
class StoreGateSvc; class StoreGateSvc;
...@@ -17,11 +18,8 @@ class IROBDataProviderSvc; ...@@ -17,11 +18,8 @@ class IROBDataProviderSvc;
* *
* It overrides the connectOutput and commitOutput methods of the base class. In this implementation, they create * It overrides the connectOutput and commitOutput methods of the base class. In this implementation, they create
* the specific online HLT output and send it out directly to the TDAQ infrastructure without using an output service. * the specific online HLT output and send it out directly to the TDAQ infrastructure without using an output service.
*
* It needs to inherit from ByteStreamCnvSvc rather than ByteStreamCnvSvcBase, because some elements of the athena
* framework (particularly converters) rely on the properties or functionality of the offline ByteStreamCnvSvc.
**/ **/
class TrigByteStreamCnvSvc : public ByteStreamCnvSvc { class TrigByteStreamCnvSvc : public ByteStreamCnvSvcBase {
public: public:
/// Standard constructor /// Standard constructor
TrigByteStreamCnvSvc(const std::string& name, ISvcLocator* svcLoc); TrigByteStreamCnvSvc(const std::string& name, ISvcLocator* svcLoc);
...@@ -34,24 +32,42 @@ public: ...@@ -34,24 +32,42 @@ public:
// ------------------------- IConversionSvc methods -------------------------- // ------------------------- IConversionSvc methods --------------------------
/// In the case of online BS data, this method creates the output FullEventFragment and fills its header /// In the case of online BS data, this method creates the output FullEventFragment and fills its header
using ByteStreamCnvSvcBase::connectOutput;
virtual StatusCode connectOutput(const std::string& outputFile) override; virtual StatusCode connectOutput(const std::string& outputFile) override;
/// In the case of online BS data, this method creates the output FullEventFragment and fills its header
StatusCode connectOutput(const std::string& outputFile, const EventContext& eventContext);
/// This overload is kept only for interface compatibility /// This overload is kept only for interface compatibility
virtual StatusCode connectOutput(const std::string& outputFile, const std::string& openMode) override; virtual StatusCode connectOutput(const std::string& outputFile, const std::string& openMode) override;
/// In the case of online BS data, this method binds and sends out the output FullEventFragment /// In the case of online BS data, this method binds and sends out the output FullEventFragment
virtual StatusCode commitOutput(const std::string& outputFile, bool do_commit) override; virtual StatusCode commitOutput(const std::string& outputFile, bool do_commit) override;
/// In the case of online BS data, this method binds and sends out the output FullEventFragment
StatusCode commitOutput(const std::string& outputFile, bool do_commit, const EventContext& eventContext);
// ------------------------- IByteStreamEventAccess methods ------------------
/// Return a pointer to the raw event for the current event context
virtual RawEventWrite* getRawEvent() override;
/// Return a pointer to the raw event for the given event context
RawEventWrite* getRawEvent(const EventContext& eventContext) const;
private: private:
// ------------------------- Helper methods ---------------------------------- // ------------------------- Helper methods ----------------------------------
/// Print contents of m_rawEventWrite /// Store new raw event in the cache
void printRawEvent(); RawEventWrite* setRawEvent(std::unique_ptr<RawEventWrite>&& rawEventWrite, const EventContext& eventContext);
/// Delete raw event from the cache
void clearRawEvent(const EventContext& eventContext);
/// Print contents of the raw event
void printRawEvent(const EventContext& eventContext) const;
/// Fill histograms from contents of a FullEventFragment /// Fill histograms from contents of a FullEventFragment
void monitorRawEvent(const std::unique_ptr<uint32_t[]>& rawEventPtr) const; void monitorRawEvent(const std::unique_ptr<uint32_t[]>& rawEventPtr) const;
/// Hack used in HLT to avoid using ThreadLocalContext, see explanation in the implementation
const EventContext* currentContext() const;
// ------------------------- Service / Tool handles -------------------------- // ------------------------- Service / Tool handles --------------------------
ServiceHandle<StoreGateSvc> m_evtStore {this, "EventStore", "StoreGateSvc"}; ServiceHandle<StoreGateSvc> m_evtStore {this, "EventStore", "StoreGateSvc"};
ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc {this, "ROBDataProvider", "ROBDataProviderSvc"}; ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc {this, "ROBDataProvider", "ROBDataProviderSvc"};
ToolHandle<GenericMonitoringTool> m_monTool {this, "MonTool", "" , "Monitoring tool"}; ToolHandle<GenericMonitoringTool> m_monTool {this, "MonTool", "" , "Monitoring tool"};
// ------------------------- Other private members ---------------------------
SG::SlotSpecificObj<std::unique_ptr<RawEventWrite>> m_rawEventWriteCache;
}; };
#endif // TRIGBYTESTREAMCNVSVC_H #endif // TRIGBYTESTREAMCNVSVC_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment