14#include "Identifier/Identifier.h"
18 template<
unsigned int n>
20 chunk(std::bitset<128> b){
21 static constexpr std::bitset<128> mask64(~0ULL);
22 static constexpr unsigned int shift{
n * 64};
23 return ((b >>shift) & mask64).to_ullong();
26 split32bitWord(uint32_t word){
27 std::vector<uint8_t>
out;
28 out.push_back(word>>24);
29 out.push_back(word>>16);
30 out.push_back(word>>8);
37 const int formatter{
static_cast<int>((fibre/12) & 0x7)};
38 const int linkNum{
static_cast<int>((fibre - (
formatter*12)) & 0xF)};
39 const int rodLink{(
formatter << 4) | linkNum};
43 hccKey(
int barrelEC, uint8_t side, uint8_t disk, uint8_t phi_mod,
int eta_mod, uint8_t eta_group){
47 bool hasTwoHccs =
false;
53 }
else if(barrelEC > 0)
sideAC=1;
56 if(sideAC==1) hcckey = hcckey | (
mask << 20);
59 hcckey = hcckey | (disk<<17);
62 if(side==1) hcckey = hcckey | (
mask << 16);
65 if(barrelEC!=0) hcckey = hcckey | (
mask << 15);
68 hcckey = hcckey | (phi_mod<<8);
71 if(disk<2 && barrelEC==0) {
73 }
else if(eta_group!=2 && barrelEC!=0){
77 eta_mod = std::abs(eta_mod);
79 if ( hasTwoHccs && ( ((eta_mod-1)/2.0 >= 2*eta_group+1 && barrelEC==0) || ((((eta_mod/2.0 >= 2*eta_group+1) && eta_mod<=7) || ((eta_mod/2.0 >= 2*eta_group) && (eta_mod>=10 && eta_mod<=13))) && barrelEC!=0))){
80 hcckey = hcckey | (
mask << 7);
83 barrelEC = (barrelEC == 0) ? 1 : 0;
86 hcckey = hcckey | (eta_group);
103 ATH_CHECK(detStore()->retrieve(itkStripsDetManager,
"ITkStrip"));
106 if (sctDetElement->swapPhiReadoutDirection()) {
115 return StatusCode::SUCCESS;
122 const std::vector<const SCT_RDORawData*>& vecRDOs)
const {
125 std::unordered_map<uint32_t, std::vector<std::bitset<256>>> allStripData;
126 std::unordered_map<uint32_t, IdentifierHash> keyToHash;
130 for (
const auto& rdo : vecRDOs) {
138 if (strip_max == 0xFFFF){
146 if((barrelEC == 0 && eta_mod > 0) || barrelEC > 0) sideAC = 1;
152 eta_group =
static_cast<uint8_t
>(std::floor((std::abs(eta_mod)-1) / 4));
154 eta_group =
static_cast<uint8_t
>(std::floor((std::abs(eta_mod)-1) / 2));
157 if(eta_mod>=0 && eta_mod<=9) eta_group =
static_cast<uint8_t
>(std::floor(eta_mod / 4));
158 else if(eta_mod>=10 && eta_mod<=13) eta_group =
static_cast<uint8_t
>(std::floor((eta_mod+2)/4));
159 else if(eta_mod>13) eta_group =
static_cast<uint8_t
>(std::floor((eta_mod-6)/2));
162 uint8_t chips_per_module = (strip_max + 1) / 128;
163 uint32_t key = hccKey(barrelEC, side, disk, phi_mod, eta_mod, eta_group);
166 keyToHash.insert({key,offlineHash});
168 ATH_MSG_DEBUG(
"barrel: "<< barrelEC<<
" sideAC: " << (uint32_t)sideAC <<
" disk: "<<(uint32_t)disk <<
" side: " << (uint32_t)side <<
" phi_mod: "<<(uint32_t)phi_mod <<
" eta_mod: " << eta_mod <<
" eta group: "<<(uint32_t)eta_group <<
" chips per module: " << (uint32_t)chips_per_module <<
" " << (uint32_t)robID <<
" " << (uint32_t)
m_itkStripsID->wafer_hash(
offlineID(rdo)));
171 auto& StripData = allStripData[key];
173 if (StripData.empty()) {
174 StripData.resize(chips_per_module);
179 int chip =
static_cast<int>(std::floor(
strip / 128));
180 int strip_position =
strip % 128;
181 int strip_logical_channel = 2*strip_position + (eta_mod & 1);
183 ATH_MSG_DEBUG(
"strip N: "<<
strip <<
" chip n: " << chip <<
" Strip position: " << strip_position <<
" Strip position logical: " << strip_logical_channel);
184 StripData[chip].set(strip_logical_channel);
187 std::vector<uint8_t> vec8Data;
188 uint32_t vectorSize = 0;
189 std::vector<uint16_t> clusters;
191 ATH_MSG_DEBUG(
"All strip data size: " << allStripData.size());
194 for (
const auto& [key, StripData] : allStripData) {
196 uint16_t ichannel = 0;
199 bool keyRecorded =
false;
202 ATH_MSG_DEBUG(
"key is: " << std::bitset<32>(key) <<
" StripData size: " << StripData.size());
204 for (
size_t i = 0; i < StripData.size(); ++i) {
206 std::bitset<256> hits = StripData[i];
216 if(clusters.empty()){
220 uint32_t hccKey = (keyRecorded) ? 0 : key;
225 vec8Data.push_back(0xed);
226 vec8Data.push_back(0x6f);
230 vec8Data.push_back(0);
231 vec8Data.push_back(0);
233 uint32_t packetLenght = (vec8Data.size()-vectorSize)+4;
234 ATH_MSG_DEBUG(
"Packet Lenght: " << (uint32_t)packetLenght <<
" " << std::bitset<32>(packetLenght));
236 std::vector<uint8_t> pktlenght = split32bitWord(packetLenght);
238 ATH_MSG_DEBUG(
"PktLenght: " << pktlenght.size() <<
" vec8Data size: " << vec8Data.size());
240 uint32_t offset = vectorSize + 4;
241 vec8Data.insert(vec8Data.begin()+offset, pktlenght.begin(), pktlenght.end());
242 vectorSize = vec8Data.size();
260 for(
auto &word: vec32Data){
268 int ptyp, uint8_t l0tag, uint8_t bc_count, uint32_t hccKey, uint16_t&
size)
const {
273 ATH_MSG_DEBUG(
"hccKey 8-bit word-4: "<<std::bitset<8>(hccKey));
274 ATH_MSG_DEBUG(
"hccKey 8-bit word-3: "<<std::bitset<8>(hccKey>>24));
275 ATH_MSG_DEBUG(
"hccKey 8-bit word-2: "<<std::bitset<8>(hccKey>>16));
276 ATH_MSG_DEBUG(
"hccKey 8-bit word-1: "<<std::bitset<8>(hccKey>>8));
278 data_encode.push_back(hccKey);
279 data_encode.push_back(hccKey>>24);
280 data_encode.push_back(hccKey>>16);
281 data_encode.push_back(hccKey>>8);
285 data_encode.push_back((
header>>8) & 0xff);
286 data_encode.push_back(
header & 0xff);
289 for(
size_t idx=0;
auto &cluster : clusters){
290 if(cluster == 0x3fe)
continue;
295 uint16_t clusterbits = ((ichannel & 0xf) << 11) | (cluster & 0x7ff);
296 ATH_MSG_DEBUG(
"Clusters: " << idx <<
": " << std::bitset<16>(clusterbits) <<
" size: " <<
size <<
" ichannel: " << ichannel);
297 data_encode.push_back((clusterbits>>8) & 0xff);
298 data_encode.push_back(clusterbits & 0xff);
309 std::vector<uint16_t> clusters;
312 std::bitset<128> dataEven;
313 std::bitset<128> dataOdd;
314 for(
int i=0; i<128; ++i){
315 dataEven[i] = inputData[2*i];
316 dataOdd[i] = inputData[2*i+1];
320 uint64_t d0l = chunk<0>(dataEven);
321 uint64_t d0h = chunk<1>(dataEven);
323 uint64_t d1l = chunk<0>(dataOdd);
324 uint64_t d1h = chunk<1>(dataOdd);
326 while (d0l or d0h or d1l or d1h){
327 if (clusters.size() > maxCluster)
break;
330 if (cluster1 != 0x3ff)
331 clusters.push_back(cluster1);
333 if (clusters.size() > maxCluster)
break;
336 if (cluster0 != 0x3ff)
337 clusters.push_back(cluster0);
340 if (clusters.empty()) {
341 clusters.push_back(0x3fe);
343 clusters.back() |=1 << 11;
351 if (bit_addr > 127)
return false;
353 return bit_addr<64 ? data_low64>>bit_addr & 1 : data_high64>>(bit_addr-64) & 1;
359 data_low64 = (data_low64 & ~(1ULL << bit_addr)) | ((uint64_t)value << bit_addr);
360 }
else if (bit_addr < 128) {
362 (data_high64 & ~(1ULL << (bit_addr-64))) | ((uint64_t)value << (bit_addr-64));
369 uint8_t hit_addr = 128;
370 uint8_t hit_mask = 0;
373 hit_addr = __builtin_ctzll(hits_low64);
374 }
else if (hits_high64){
375 hit_addr = __builtin_ctzll(hits_high64) + 64;
378 hit_mask =
getBit_128b(hit_addr+1, hits_high64, hits_low64) << 2
379 |
getBit_128b(hit_addr+2, hits_high64, hits_low64) << 1
380 |
getBit_128b(hit_addr+3, hits_high64, hits_low64);
382 for (
int i=0; i<4; ++i)
383 setBit_128b(hit_addr+i, 0, hits_high64, hits_low64);
385 if (hit_addr == 128) {
388 hit_addr += isSecondRow<<7;
389 return hit_addr << 3 | hit_mask;
395 int num8Words{
static_cast<int>(vec8Words.size())};
396 if (num8Words % 4 != 0) {
398 while (num8Words % 4 != 0) {
399 vec8Words.push_back(0x40);
404 const unsigned short int numWords{4};
405 const unsigned short int position[numWords]{0, 8, 16, 24};
406 unsigned short int arr8Words[numWords]{0, 0, 0, 0};
408 for (
int i{0}; i<num8Words; i += numWords) {
409 for (
int j{0}; j<numWords; j++) {
410 arr8Words[j] = vec8Words[i + j];
412 const uint32_t uint32Word{
set32Bits(arr8Words, position, numWords)};
413 vec32Words.push_back(uint32Word);
422 uint32_t uint32Word{0};
424 uint32_t uint8Word{0};
425 for (uint16_t i{0}; i<numWords; i++) {
426 uint8Word =
static_cast<uint32_t
>(*(arr8Words + i));
427 pos =
static_cast<uint32_t
>(*(position + i));
428 uint32Word |= (uint8Word << pos);
451 return static_cast<uint32_t
>(
m_cabling->getOnlineIdFromHash(offlineIDHash));
456 return rodLinkFromOnlineID(
onlineID(rdo));
507 uint8_t bcid_low = bc_cout & 0x7;
510 const uint16_t Header{
static_cast<uint16_t
>(((uint8_t)typ << 12) | (0x1 << 11) | (l0tag & 0x7f) << 4 | (bcid_low) << 1 | bc_parity)};
520 const uint16_t linkHeader{
static_cast<uint16_t
>(0x2000 | (
m_condensed.value() << 8) | rodLink)};
526 const int rodLink{rodLinkFromOnlineID(
m_cabling->getOnlineIdFromHash(linkHash))};
527 const uint16_t linkHeader{
static_cast<uint16_t
>(0x2000 | errorWord | (
m_condensed.value() << 8) | rodLink)};
533 const uint16_t linkTrailer{
static_cast<uint16_t
>(0x4000 | errorWord)};
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
This is an Identifier helper class for the SCT subdetector.
size_t size() const
Number of registered mappings.
std::uint32_t fibre() const
Return the fibre.
const SCT_ID * m_itkStripsID
Identifier helper class for the ITkStrips subdetector that creates compact Identifier objects and Ide...
uint16_t getStripMax(const SCT_RDORawData *rdo) const
Get the maxumum strip value info from the RDO.
uint32_t onlineID(const SCT_RDORawData *rdo) const
Get the online Identifier from the RDO.
ToolHandle< IITkStripCablingTool > m_cabling
Providing mappings of online and offline identifiers and also serial numbers.
Identifier offlineID(const SCT_RDORawData *rdo) const
Get the offline Identifier from the RDO.
uint16_t getHeaderPhysicsPacket(int typ, uint8_t l0tag, uint8_t bc_count) const
Get the 16-bit word for a header with Type (PR or LP), L0Tag event and BCID.
BooleanProperty m_condensed
Example Boolean used to determine decoding mode, maybe unused finally.
int getBarrelEC(const SCT_RDORawData *rdo) const
Get the barrel/endcape info from the RDO.
virtual void fillROD(std::vector< uint32_t > &vec32Data, const uint32_t &robID, const std::vector< const SCT_RDORawData * > &vecRDOs) const override
Main Convert method.
void setBit_128b(uint8_t bit_addr, bool value, uint64_t &data_high64, uint64_t &data_low64) const
uint16_t clusterFinder_sub(uint64_t &hits_high64, uint64_t &hits_low64, bool isSecondRow) const
bool getBit_128b(uint8_t bit_addr, uint64_t data_high64, uint64_t data_low64) const
int getRODLink(const SCT_RDORawData *rdo) const
Get the ROD link number info in the RDO header data.
std::atomic< uint8_t > m_l0tag
uint16_t getHeaderUsingRDO(const SCT_RDORawData *rdo) const
Get the 16-bit word for a header for a hit.
int getEtaModule(const SCT_RDORawData *rdo) const
Get the eta value info from the RDO.
uint16_t getTrailer(const int &errorWord) const
Get the 16-bit word for a trailer, with or without ByteStream errors.
int getSide(const SCT_RDORawData *rdo) const
Get the side info from the RDO.
int getStrip(const SCT_RDORawData *rdo) const
Get the strip number info from the RDO.
std::vector< uint16_t > clusterFinder(const std::bitset< 256 > &inputData, const uint8_t maxCluster=63) const
@breif Method to set pairs of 8 bit words to a 32 bit word.
uint8_t getPhiModule(const SCT_RDORawData *rdo) const
Get the phi value info from the RDO.
uint8_t getDiskLayer(const SCT_RDORawData *rdo) const
Get disk/layer info from the RDO.
uint32_t set32Bits(const unsigned short int *arr8Words, const unsigned short int *position, const unsigned short int &numWords) const
void encodeData(const std::vector< uint16_t > &clusters, const uint16_t ichannel, std::vector< uint8_t > &data_encode, int typ, uint8_t l0tag, uint8_t bc_count, uint32_t hccKey, uint16_t &size) const
ToolHandle< ITkStripDataRateMonTool > m_dataRateMonTool
virtual StatusCode initialize() override
Initialize.
std::set< Identifier > m_swapModuleID
Swap Module identifier, set by SCTRawContByteStreamTool.
uint16_t getHeaderUsingHash(const IdentifierHash &linkHash, const int &errorWord) const
Get the 16-bit word for a header for a link with a ByteStream error.
void packFragments(std::vector< uint8_t > &vec8Words, std::vector< uint32_t > &vec32Words) const
Method to pack vector of 8 bit words intto a vector of 32 bit words.
bool getParity_8bits(uint8_t val) const
std::atomic< uint8_t > m_bcid
Method to encode RDO data to vector of 16 bin words.
This is a "hash" representation of an Identifier.
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
virtual const SiDetectorElementCollection * getDetectorElementCollection() const override
access to whole collectiom
Class to hold the SiDetectorElement objects to be put in the detector store.
Class to hold geometrical description of a silicon detector element.
virtual Identifier identify() const override final
::StatusCode StatusCode
StatusCode definition for legacy code.
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the elements of the container.