ATLAS Offline Software
ITkPixelDecodingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "ITkPixelDecodingAlg.h"
6 #include "StoreGate/ReadHandle.h"
7 #include "eformat/ROBFragment.h"
8 
9 #define ENABLE_TIMING = true;
10 #ifdef ENABLE_TIMING
11 #define SCOPED_TIMER(name, msg) ITkPixelDecoding::ScopedTimer timer_##__LINE__(name, msg)
12 #else
13 #define SCOPED_TIMER(name, msg)
14 #endif
15 
16 
17 using namespace itksw::pix::endec;
18 
19 ITkPixelDecodingAlg::ITkPixelDecodingAlg(const std::string& name, ISvcLocator* pSvcLocator) :
20  AthReentrantAlgorithm(name, pSvcLocator)
21 {
22 
23 }
24 
25 
27 {
28  ATH_CHECK(m_robDataProviderSvc.retrieve());
29 
31 
32  ATH_CHECK(detStore()->retrieve(m_idHelper, "PixelID"));
33 
35 
36  //this should go into the cabling likely...
37  for (size_t hash = 0; hash < m_idHelper->wafer_hash_max(); hash++){
38  m_sourceIDs.push_back(m_idHelper->wafer_id(hash).get_identifier32().get_compact() | 0b00 );
39  m_sourceIDs.push_back(m_idHelper->wafer_id(hash).get_identifier32().get_compact() | 0b10 );
40  m_sourceIDs.push_back(m_idHelper->wafer_id(hash).get_identifier32().get_compact() | 0b01 );
41  m_sourceIDs.push_back(m_idHelper->wafer_id(hash).get_identifier32().get_compact() | 0b11 );
42  }
43 
44  return StatusCode::SUCCESS;
45 }
46 
47 StatusCode ITkPixelDecodingAlg::execute(const EventContext& ctx) const
48 {
49  //Timing
50  SCOPED_TIMER("ITkPixelDecodingAlg::execute", msg());
51 
52  //Retrieve the ROB IDs from cabling - dummy as of now, happens in initialize()
54  const ITkPixelCablingData* cabling = *cablingData;
55 
56  //Instantiate the output. RN using the old pixel RDO, nothing fancier than that
57  std::unique_ptr<PixelRDO_Container> rdoCont = std::make_unique<PixelRDO_Container>(m_idHelper->wafer_hash_max());
58 
59  //Instantiate the decoder. Doing this once per event is fine and MT-safe
60  //It needs a "callback" that implements methods required by concepts. This is
61  //the drawback of using an external code (by ITk online sw). Each of these methods
62  //is then called at appropriate places in the decoding. The decoder is configured
63  //with data format options. The callback can do whatever with the decoded hits
64  //e. g. print them on the screen or put them in a container as RDOs.
65  DataFormat fmt;
66  fmt.options.en_chip_id = true;
67  fmt.options.en_eos = true;
68  PixelCallbacks::RDOCallback cb(rdoCont.get(), m_idHelper);
69  DecCore<PixelCallbacks::RDOCallback> core(fmt, cb);
70  core.initialize();
71 
72  //Invoke ROBDataProviderService, fetch the concerned ROBs.
73  std::vector<const eformat::ROBFragment<const uint32_t*>*> ROBs;
74  m_robDataProviderSvc->getROBData(ctx, m_sourceIDs, ROBs);
75  ATH_MSG_DEBUG("Retrieved " << ROBs.size() << " fragments");
76 
77  //We can now loop over the payloads of the ROB fragments retrieved earlier.
78  //There's as of now a little annoyance that the decoder eats 64 bit frames
79  //but the ROBs come in 32 bits. At least they have the same endian polarity.
80  //Nevertheless, we need to rearrange them.
81  std::vector<uint64_t> payload64;
82  std::array<std::vector<uint64_t>, 4> split_streams;
83  for (const auto& ROB : ROBs){
84  const uint32_t* payload = ROB->rod_data();
85  uint32_t length = ROB->rod_ndata();
86 
87  //Translate the data into 64 bits. We know the length, so we can reserve
88  //the space to avoid reallocation. Since the frames are always 64 bits split
89  //into 32, they'll always be divisible by 2 without modulo.
90  payload64.clear();
91  payload64.resize(length / 2);
92  for (uint32_t word = 0; word < length; word += 2){
93  payload64[word / 2] = ((uint64_t)(payload[word]) << 32) | payload[word + 1];
94  }
95 
96 
97  //Need to set the correct offline ID for this ROB
98  ITkPixelCabling::ModuleInfo mi = cabling->offlineModuleInfo(ROB->rob_source_id());
99  cb.setOfflineID(mi.id.get_identifier32().get_compact());
100 
101  //Set transform type
103 
104  //If this is a merged quad, it has all 4 chips in one ROB
105  //In such case we need to decode them separately. Otherwise
106  //It's a 1:1 correspondence
107 
109  cb.setChipID(0);
110  core.decode(payload64);
111  }
112  else {
113  //split according to chip ID, which is always in highest bits 1 and 2
114  for (auto &v : split_streams) v.clear();
115  for (const uint64_t& word64: payload64) split_streams[(word64 >> 61) & 0b11].push_back(word64);
116  for (uint8_t chipID = 0; chipID < 4; chipID++){
117  if (!split_streams[chipID].empty()){
118  cb.setChipID(chipID);
119  core.decode(split_streams[chipID]);
120  }
121  }
122  }
123  }
124 
125  //The container is filled by now. We can write it to SG
126  SG::WriteHandle<PixelRDO_Container> pixelRDOContainerHandle(m_pixelRDOKey, ctx);
127  ATH_CHECK(pixelRDOContainerHandle.record(std::move(rdoCont)));
128 
129  return StatusCode::SUCCESS;
130 }
131 
133  return StatusCode::SUCCESS;
134 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ITkPixelDecodingAlg::m_sourceIDs
std::vector< uint32_t > m_sourceIDs
Definition: ITkPixelDecodingAlg.h:49
ITkPixelDecodingAlg.h
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
PixelCallbacks::RDOCallback::setChipID
void setChipID(const uint8_t &chipID)
Definition: ITkPixelDecodingAlg.h:124
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
fmt
const char *const fmt
Definition: TripleGaussCollFit.cxx:84
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:360
ITkPixelDecodingAlg::m_pixelCablingKey
SG::ReadCondHandleKey< ITkPixelCablingData > m_pixelCablingKey
Definition: ITkPixelDecodingAlg.h:45
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
ITkPixelDecodingAlg::m_idHelper
const PixelID * m_idHelper
Definition: ITkPixelDecodingAlg.h:51
ITkPixelCabling::ModuleInfo::transform
TransformType transform
Definition: ITkPixelCablingData.h:52
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ITkPixelDecodingAlg::m_pixelRDOKey
SG::WriteHandleKey< PixelRDO_Container > m_pixelRDOKey
Definition: ITkPixelDecodingAlg.h:47
ITkPixelDecodingAlg::m_robDataProviderSvc
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
Definition: ITkPixelDecodingAlg.h:43
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
PixelID::wafer_hash_max
size_type wafer_hash_max() const
Definition: PixelID.cxx:833
ITkPixelCablingData
Definition: ITkPixelCablingData.h:105
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ITkPixelCabling::ModuleInfo
Definition: ITkPixelCablingData.h:49
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
PixelModuleFeMask_create_db.payload
string payload
Definition: PixelModuleFeMask_create_db.py:69
python.PyAthena.v
v
Definition: PyAthena.py:154
SCOPED_TIMER
#define SCOPED_TIMER(name, msg)
Definition: ITkPixelDecodingAlg.cxx:11
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
ITkPixelDecodingAlg::ITkPixelDecodingAlg
ITkPixelDecodingAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: ITkPixelDecodingAlg.cxx:19
PixelCallbacks::RDOCallback
Definition: ITkPixelDecodingAlg.h:73
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
ITkPixelDecodingAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: ITkPixelDecodingAlg.cxx:47
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TrigPartialEventBuildingConfig.ROBs
ROBs
Definition: TrigPartialEventBuildingConfig.py:122
ReadHandle.h
Handle class for reading from StoreGate.
ITkPixelDecodingAlg::finalize
virtual StatusCode finalize() override
Definition: ITkPixelDecodingAlg.cxx:132
ITkPixelDecodingAlg::initialize
virtual StatusCode initialize() override
Definition: ITkPixelDecodingAlg.cxx:26
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
ITkPixelCabling::ModuleInfo::type
ModuleType type
Definition: ITkPixelCablingData.h:51
PixelCallbacks::RDOCallback::setTransformType
void setTransformType(const ITkPixelCabling::TransformType &transform)
Definition: ITkPixelDecodingAlg.h:129
ITkPixelCabling::MergedQuad
@ MergedQuad
Definition: ITkPixelCablingData.h:28
ITkPixelCabling::ModuleInfo::id
ID id
Definition: ITkPixelCablingData.h:50
PixelCallbacks::RDOCallback::setOfflineID
void setOfflineID(const uint32_t &offlineID)
Definition: ITkPixelDecodingAlg.h:119