Commit ce0fdca7 authored by Tomasz Bold's avatar Tomasz Bold Committed by Graeme Stewart
Browse files

initial version of the BS converter (standalone self-tested) (TrigFTKByteStream-00-00-00)

parent 20e1c446
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef TrigTrigFTKByteStreamCnv_h
#define TrigTrigFTKByteStreamCnv_h
/**********************************************************************************
* @Project: FTK
* @Package: TrigFTKByteStream
* @Class : TrigFTKByteStreamCnv
*
* @brief Gaudi bytestream Converter for the TrigFTK class
*
*
* File and Version Information:
* $Id:
**********************************************************************************/
#include "GaudiKernel/Converter.h"
#include "GaudiKernel/CnvFactory.h"
#include "GaudiKernel/ToolHandle.h"
#include "GaudiKernel/ServiceHandle.h"
#include "ByteStreamCnvSvcBase/ByteStreamAddress.h"
#include "TrigFTKByteStream/TrigFTKByteStreamTool.h"
//#include <string>
// forward declarations
class IROBDataProviderSvc;
class IByteStreamEventAccess;
// Externals
extern unsigned char ByteStream_StorageType;
namespace FTK {
class FTKByteStreamTool;
/**
@class TrigFTKByteStreamCnv
@brief Gaudi bytestream Converter for the FTKAthTrackContainer class
This class essentially provides two methods:
1. createObj(IOpaqueAddress*, DataObject*&)
2. createRep(DataObject*, IOpaqueAddress*& )
The first one creates a DataObject from persistent information, captured in
IOpaqueAddress, and the second is supposed to write the DataObject to
a persistent representation. Here, DataObject will be casted to TrigFTK
see here for a general ByteStream converter description:
http://atlas-sw.cern.ch/cgi-bin/viewcvs-atlas.cgi/offline/Event/ByteStreamCnvSvc/doc/ByteStream.txt
beginning of this file:<br>
ByteStream conversion Service (ByteStreamCnvSvc) provides a means to
convert the raw data in the ByteStream format to and from the transient
representation, Raw Data Objects (RDO). In Gaudi's terminology, ByteStream
can be considered as a persistency for reading and storing raw data. In
practice, the source of the ByteStream can be a file, or the online data
source (or its emulation) through network, for example. Together with the
IdentifiableContainer, used to contain the Raw Data Objects, ByteStreamCnvSvc
provides a mechanism for creating the RDOs on demand.
*/
class TrigFTKByteStreamCnv : public Converter {
public:
TrigFTKByteStreamCnv(ISvcLocator* svcloc); //!< std Gaudi converter constructor
~TrigFTKByteStreamCnv();
virtual StatusCode initialize(); //!< Gaudi initialize
virtual StatusCode finalize(); //!< Gaudi finalize
virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj); //!< create RDO (TrigFTK) from bytestream
virtual StatusCode createRep(DataObject* pObj, IOpaqueAddress*& pAddr); //!< create bytestream from RDOs (TrigFTK)
// Storage type and class ID
static unsigned char storageType() { return ByteStream_StorageType; } //!< used for the converter
static const CLID& classID(); //!< CLID
long repSvcType() const { return i_repSvcType(); } //!< return repSvcType
friend class CnvFactory<TrigFTKByteStreamCnv>; //!< declare factory as friend
private:
MsgStream* m_log; //!< std message stream
ToolHandle< TrigFTKByteStreamTool > m_tool ; //!< tool for conversion work
ServiceHandle< IByteStreamEventAccess > m_ByteStreamEventAccess; //!< Gaudi helper
ServiceHandle< IROBDataProviderSvc > m_robDataProvider; //!< Gaudi ROB helper
};
}
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/**********************************************************************************
* @Project: FTK
* @Package: TrigFTKByteStream
* @Class : TrigFTKByteStreamTool
*
* @brief Gaudi bytestream Converter tool for the TrigFTK class
*
*
* File and Version Information:
* $Id:
**********************************************************************************/
#ifndef TrigTrigFTKByteStreamTool_h
#define TrigTrigFTKByteStreamTool_h
#include "AthenaBaseComps/AthAlgTool.h"
/* To be able to use OFFLINE_FRAGMENTS_NAMESPACE */
#include "ByteStreamData/RawEvent.h"
#include "ByteStreamData/ROBData.h"
#include "ByteStreamCnvSvcBase/FullEventAssembler.h"
/* the RDO structure */
#include "TrigFTK_RawData/FTK_RawTrackContainer.h"
#include "eformat/SourceIdentifier.h"
// forward declarations
class IROBDataProviderSvc;
namespace FTK {
/**
@class TrigFTKByteStreamTool
@brief An AlgTool class to provide conversion from TrigFTK to ByteStream, and fill it in RawEvent
This tool is used by the Gaudi converter class: TrigFTKByteStreamCnv.
*/
class TrigFTKByteStreamTool: public AthAlgTool {
public:
TrigFTKByteStreamTool( const std::string& type, const std::string& name,
const IInterface* parent ) ; //!< std Gaudi tool constructor
virtual ~TrigFTKByteStreamTool() ; //!< virtual destructor
static const InterfaceID& interfaceID( ) ; //!< std Gaudi interface
virtual StatusCode initialize(); //!< std Gaudi initialize -> call initialize from base class
virtual StatusCode finalize(); //!< std Gaudi finalize -> call finalize from base class
/// @brief convert ROBData to FTK_RawTrackContainer this function should be called from createObj
StatusCode convert(IROBDataProviderSvc& dataProvider, FTK_RawTrackContainer*& result,
const std::string& objName);
/// @brief convert FTK_RawTrackContainer to ByteStream this function should be called from createRep
StatusCode convert( const FTK_RawTrackContainer* result, RawEventWrite* re,
const std::string& objName);
private:
FullEventAssembler<> m_fea;
};
}
#endif
package TrigFTKByteStream
author Bartosz Mindur <bartosz.mindur@cern.ch>
author Tomasz Bold <tomasz.bold@cern.ch>
use AtlasPolicy AtlasPolicy-*
use GaudiInterface GaudiInterface-* External
use DataCollection DataCollection-* External
use AthenaBaseComps AthenaBaseComps-* Control
use ByteStreamCnvSvcBase ByteStreamCnvSvcBase-* Event
use ByteStreamData ByteStreamData-* Event
use TrigFTK_RawData TrigFTK_RawData-* Trigger/TrigFTK
library TrigFTKByteStream *.cxx components/*.cxx
apply_pattern component_library
private
use AthenaKernel AthenaKernel-* Control
use StoreGate StoreGate-* Control
use TestPolicy TestPolicy-*
use TestTools TestTools-* AtlasTest
apply_pattern CppUnit name=FTKEncodeDecode_test files="-s=../test FTKEncodeDecode_CppUnit.cxx"
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#include "GaudiKernel/MsgStream.h"
#include "FTKByteStreamDecoderEncoder.h"
using namespace FTKByteStreamDecoderEncoder;
namespace {
void packNumberOfTracks(uint16_t nTracksLowPt, uint16_t nTracksHighPt, std::vector<uint32_t>& rod ) {
uint32_t size_data = nTracksHighPt;
size_data <<= 16;
size_data |= nTracksLowPt;
rod.push_back( size_data );
}
void unpackNumberOfTracks(OFFLINE_FRAGMENTS_NAMESPACE::PointerType rodData,
uint16_t& nTracksLowPt, uint16_t& nTracksHighPt, uint32_t& nTracks) {
nTracksLowPt = rodData[0] & 0xffff;
nTracksHighPt = (rodData[0]>>16) & 0xffff;
nTracks = nTracksLowPt; // conversion to 32 + assignement
nTracksLowPt += nTracksHighPt; // adding to more capable type
}
void packPixelCluster(const FTK_RawPixelCluster& cluster, std::vector<uint32_t>& payload) {
payload.push_back( cluster.getWordA() );
payload.push_back( cluster.getWordB() );
}
void unpackPixCluster(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, FTK_RawPixelCluster& cluster) {
cluster.setWordA(*data);
cluster.setWordB(*(data+1));
}
void packSCTCluster(const FTK_RawSCT_Cluster& cluster, std::vector<uint32_t>& payload) {
payload.push_back( cluster.getWord() );
}
void unpackSCTCluster(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, FTK_RawSCT_Cluster& cluster) {
cluster.setWord(*data);
}
void packTrack(const FTK_RawTrack* track, std::vector<uint32_t>& payload) {
payload.push_back( track->getTH1() );
payload.push_back( track->getTH2() );
payload.push_back( track->getTH3() );
payload.push_back( track->getTH4() );
payload.push_back( track->getTH5() );
for ( std::vector<FTK_RawPixelCluster>::const_iterator it = track->getPixelClusters().begin();
it != track->getPixelClusters().end(); ++it ) {
packPixelCluster(*it, payload);
}
for ( std::vector<FTK_RawSCT_Cluster>::const_iterator it = track->getSCTClusters().begin();
it != track->getSCTClusters().end(); ++it ) {
packSCTCluster(*it, payload);
}
}
FTK_RawTrack* unpackFTTrack( OFFLINE_FRAGMENTS_NAMESPACE::PointerType data) {
FTK_RawTrack* track = new FTK_RawTrack(data[0], data[1], data[2], data[3], data[4]); // first five words are track params
data += TrackParamsBlobSize;
// get pixel hits
track->getPixelClusters().resize(NPixLayers);
for ( size_t i = 0; i < size_t(NPixLayers); ++i) {
size_t offset = PixHitParamsBlobSize*i;
unpackPixCluster(data+offset, track->getPixelCluster(i) );
}
data += PixHitParamsBlobSize*NPixLayers;
// gets SCT hits
track->getSCTClusters().resize(NSCTLayers);
for ( size_t i = 0; i < size_t(NSCTLayers); ++i) {
size_t offset = SCTHitParamsBlobSize*i;
unpackSCTCluster(data+offset, track->getSCTCluster(i) );
}
// no more shifts needed
return track;
}
} // eof internal namespace
namespace FTKByteStreamDecoderEncoder {
StatusCode encode(const FTK_RawTrackContainer* container, std::vector<uint32_t>& payload,
MsgStream& /*msg*/) {
// do not know yet what tracks are high pT, so all will be low pT
payload.reserve( 1 + TrackParamsBlobSize * container->size() );
packNumberOfTracks( container->size(), 0, payload );
for ( FTK_RawTrackContainer::const_iterator track = container->begin();
track != container->end(); ++track ) {
packTrack(*track, payload);
}
return StatusCode::SUCCESS;
}
StatusCode decode(OFFLINE_FRAGMENTS_NAMESPACE::PointerType rodData, FTK_RawTrackContainer* result,
MsgStream& msg) {
uint16_t nTracksHighPt;
uint16_t nTracksLowPt;
uint32_t nTracks;
unpackNumberOfTracks(rodData, nTracksLowPt, nTracksHighPt, nTracks);
msg << MSG::DEBUG << "[convert to FTK_RawTrackContainer] ntracks All: " << nTracks
<< " Lo pT: " << nTracksLowPt
<< " Hi pT: " << nTracksHighPt << endreq;
rodData++;
result->reserve(result->size() + nTracks);
for ( size_t i = 0; i < nTracks; ++i ) {
FTK_RawTrack* track = unpackFTTrack( rodData );
rodData += TrackBlobSize;
result->push_back(track);
}
return StatusCode::SUCCESS;
}
size_t decodeNumberOfTracks(OFFLINE_FRAGMENTS_NAMESPACE::PointerType rodData) {
uint16_t low, high;
uint32_t all;
unpackNumberOfTracks(rodData, low, high, all);
return all;
}
}
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef FTKBYTESTREAMDECODERENCODER_H
#define FTKBYTESTREAMDECODERENCODER_H
#include "ByteStreamData/RawEvent.h"
#include "TrigFTK_RawData/FTK_RawTrackContainer.h"
#include "TrigFTK_RawData/FTK_RawPixelCluster.h"
#include "TrigFTK_RawData/FTK_RawSCT_Cluster.h"
namespace FTKByteStreamDecoderEncoder {
const size_t TrackBlobSize = 21; // magic number from BS specification
const size_t TrackParamsBlobSize = 5; // --||--
const size_t PixHitParamsBlobSize = 2; // --||--
const size_t SCTHitParamsBlobSize = 1; // --||--
const size_t NPixLayers=4;
const size_t NSCTLayers=8;
StatusCode decode(OFFLINE_FRAGMENTS_NAMESPACE::PointerType rodData, FTK_RawTrackContainer* result,
MsgStream& msg);
size_t decodeNumberOfTracks(OFFLINE_FRAGMENTS_NAMESPACE::PointerType rodData);
StatusCode encode(const FTK_RawTrackContainer* result, std::vector<uint32_t>& payload,
MsgStream& msg);
}
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#include "FTKDump.h"
#include "TrigFTK_RawData/FTK_RawTrackContainer.h"
#include "AthenaKernel/errorcheck.h"
#include "GaudiKernel/MsgStream.h"
FTKDump::FTKDump(const std::string &name, ISvcLocator *pSvcLocator)
: AthAlgorithm( name, pSvcLocator ) {
m_log = new MsgStream(messageService(), "FTKDump");
}
FTKDump::~FTKDump(){
delete m_log;
}
StatusCode FTKDump::initialize() {
return StatusCode::SUCCESS;
}
StatusCode FTKDump::execute() {
const FTK_RawTrackContainer* tracks_ptr;
CHECK(evtStore()->retrieve(tracks_ptr, "dummy_tracks"));
//ATH_MSG_INFO( "Got the tracks" );
(*m_log) << MSG::INFO << "Got no of tracks: " << tracks_ptr->size() << endreq;
return StatusCode::SUCCESS;
}
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id$
#ifndef FTK_DUMP_EXAMPLE_H
#define FTK_DUMP_EXAMPLE_H
// Gaudi/Athena include(s):
#include "AthenaBaseComps/AthAlgorithm.h"
#include "GaudiKernel/ToolHandle.h"
class MsgStream;
/**
* @short Example for the usage of FTKDump in C++
*
* @author Bartosz Mindur <bartosz.mindur@cern.ch> AGH-UST Krakow
*
* $Revision$
* $Date$
*/
class FTKDump : public AthAlgorithm {
public:
/// Regular algorithm constructor
FTKDump( const std::string &name, ISvcLocator *pSvcLocator );
~FTKDump();
/// Function called at the beginning of the job
virtual StatusCode initialize();
/// Function called at each event
virtual StatusCode execute();
private:
MsgStream* m_log; //!< std message stream
}; // class FTKDump
#endif // FTK_DUMP_EXAMPLE_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#include "ByteStreamData/ROBData.h"
#include "ByteStreamCnvSvcBase/ByteStreamCnvSvcBase.h"
#include "ByteStreamCnvSvcBase/ByteStreamAddress.h"
#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
#include "GaudiKernel/MsgStream.h"
#include "GaudiKernel/CnvFactory.h"
#include "GaudiKernel/StatusCode.h"
#include "GaudiKernel/DataObject.h"
#include "GaudiKernel/IRegistry.h"
#include "TrigFTKByteStream/TrigFTKByteStreamCnv.h"
#include "StoreGate/StoreGate.h"
//#include "CLIDSvc/CLASS_DEF.h"
// Tool
#include "GaudiKernel/IToolSvc.h"
//------------------------------------------------------------------------------
FTK::TrigFTKByteStreamCnv::TrigFTKByteStreamCnv(ISvcLocator* svcloc) :
Converter(ByteStream_StorageType, classID(),svcloc),
m_log(0),
m_tool("FTK::TrigFTKByteStreamTool"),
m_ByteStreamEventAccess("ByteStreamCnvSvc", "TrigFTKByteStreamCnv"),
m_robDataProvider("ROBDataProviderSvc", "TrigFTKByteStreamCnv")
{ }
FTK::TrigFTKByteStreamCnv::~TrigFTKByteStreamCnv() {
delete m_log;
}
//------------------------------------------------------------------------------
const CLID& FTK::TrigFTKByteStreamCnv::classID()
{
return ClassID_traits<FTK_RawTrackContainer>::ID() ;
}
//------------------------------------------------------------------------------
StatusCode FTK::TrigFTKByteStreamCnv::finalize()
{
return StatusCode::SUCCESS;
}
//------------------------------------------------------------------------------
StatusCode FTK::TrigFTKByteStreamCnv::initialize()
{
StatusCode sc = Converter::initialize();
if(StatusCode::SUCCESS!=sc)
{
return sc;
}
m_log = new MsgStream(messageService(), "TrigFTKByteStreamCnv");
(*m_log) << MSG::DEBUG << "TrigFTKByteStreamCnv in initialize() " <<endreq;
//Get ByteStreamCnvSvc
if ( m_ByteStreamEventAccess.retrieve().isFailure() ) {
(*m_log) << MSG::FATAL << "failed to retrieve ByteStreamEventAccess service: "
<< m_ByteStreamEventAccess << endreq;
return StatusCode::FAILURE;
} else {
(*m_log) << MSG::DEBUG << "successfully retrieved ByteStreamEventAccess service: "
<< m_ByteStreamEventAccess << endreq;
}
// get the converter tool:
if ( m_tool.retrieve().isFailure() ) {
(*m_log) << MSG::FATAL << "failed to retrieve converter tool : "
<< m_tool << endreq;
return StatusCode::FAILURE;
} else {
(*m_log) << MSG::DEBUG << "successfully retrieved converter tool: "
<< m_tool << endreq;
}
// Get ROBDataProvider
if (m_robDataProvider.retrieve().isFailure()) {
(*m_log) << MSG::FATAL << "failed to retrieve ROBDataProviderSvc service: "
<< m_robDataProvider << endreq;
return StatusCode::FAILURE;
}
(*m_log) << MSG::DEBUG << "successfully retrieved ROBDataProviderSvc service: "
<< m_robDataProvider << endreq;
return StatusCode::SUCCESS;
}
//------------------------------------------------------------------------------
StatusCode FTK::TrigFTKByteStreamCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj)
{
FTK_RawTrackContainer* result(0);
ByteStreamAddress *pBS_Addr;
pBS_Addr = dynamic_cast<ByteStreamAddress*>(pAddr);
if(!pBS_Addr) {
(*m_log) << MSG::ERROR << " Can not cast to ByteStreamAddress " << endreq ;
return StatusCode::FAILURE;
}
const std::string object_name = *(pBS_Addr->par()) ; //< Params for tool converter
std::vector<ROBData> vRobData;
StatusCode sc = m_tool->convert(*m_robDataProvider, result, object_name); //<Actual converstion
if (sc != StatusCode::SUCCESS) {
(*m_log) << MSG::ERROR << "Failed to convert object " << object_name << endreq;
return sc;
}
pObj = StoreGateSvc::asStorable(result);
return sc;
}
//------------------------------------------------------------------------------
StatusCode FTK::TrigFTKByteStreamCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr)
{
FTK_RawTrackContainer* result = 0;
StoreGateSvc::fromStorable(pObj, result);
if (!result) {
(*m_log) << MSG::ERROR << " Cannot cast to FTK_RawTrackContainer " << endreq ;
return StatusCode::FAILURE;
}