13#include "eformat/SourceIdentifier.h"
32uint32_t bitFieldSize(uint32_t word, uint8_t offset, uint8_t size) {
33 return (word >> offset) & ((1U << size) - 1);
36uint32_t crateModuleMask(uint8_t crate, uint8_t module) {
37 return (crate << 8) | (1 << 4) | module;
40uint32_t coolId(uint8_t crate, uint8_t module, uint8_t channel) {
43 return (crateModuleMask(crate, module) << 16) | (pin << 8) | asic;
46int16_t pedCorrection(uint16_t twoBytePedCor) {
47 return twoBytePedCor > 511? (twoBytePedCor - 1024): twoBytePedCor;
51std::string noAuxSuffix(
const std::string& name) {
52 if ((
name.size() > 4) && (
name.substr(
name.size()-4, 4) ==
"Aux.")) {
53 return name.substr(0,
name.size() - 4);
66 m_errorTool(
"LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
67 m_ppmMaps(
"LVL1::PpmMappingTool/PpmMappingTool"),
72 declareInterface<PpmByteStreamReadV1V2Tool>(
this);
75 "Crate/Module/Channel to Eta/Phi/Layer mapping tool");
77 "Get ROB source IDs service");
95 return StatusCode::SUCCESS;
103 return StatusCode::SUCCESS;
120 for (; rob != robEnd; ++rob) {
123 if (!
sc.isSuccess()) {
129 return StatusCode::SUCCESS;
144 const std::vector<uint32_t>& vID(
ppmSourceIDs(state, sgKey));
147 m_robDataProvider->getROBData(Gaudi::Hive::currentContext(), vID, robFrags,
"PpmByteStreamxAODReadTool");
148 ATH_MSG_DEBUG(
"Number of ROB fragments:" << robFrags.size());
151 return StatusCode::SUCCESS;
159 auto rob = **robIter;
162 "Treating ROB fragment source id #" << MSG::hex << rob.rob_source_id());
172 if (rob.nstatus() > 0) {
178 return StatusCode::FAILURE;
186 rob.rod_data(payloadBeg);
187 payloadEnd = payloadBeg + rob.rod_ndata();
188 payload = payloadBeg;
190 if (payload == payloadEnd) {
192 return StatusCode::FAILURE;
197 uint16_t rodVer = rob.rod_version() & 0xffff;
198 uint32_t rodRunNumber = rob.rod_run_no() & 0xffffff;
199 state.
m_verCode = ((rodVer & 0xfff) << 4) | 1;
204 return StatusCode::FAILURE;
207 ATH_MSG_DEBUG(
"Treating crate " << rodCrate <<
" slink " << rodSlink);
211 return StatusCode::FAILURE;
215 "Run number: " << MSG::dec << rodRunNumber <<
endmsg
216 <<
"Version code: 0x" << MSG::hex <<
int(state.
m_verCode) << MSG::dec
217 <<
endmsg <<
"LUT triggered slice offset: "
220 <<
endmsg <<
"FADC baseline lower bound: "
224 uint8_t blockType = 0;
227 for (; payload != payloadEnd; ++payload) {
238 blockType = (*payload >> 28) & 0xf;
240 if ((blockType & 0xd) == 0xc) {
249 subBlock = blockType & 0xe;
250 }
else if (blockType == (subBlock | 1)) {
256 case eformat::TDAQ_CALO_PREPROC:
269 return StatusCode::SUCCESS;
286 return StatusCode::FAILURE;
288 return StatusCode::SUCCESS;
322 <<
"' for rob version '"
324 << MSG::dec <<
"'" );
325 return StatusCode::FAILURE;
327 return StatusCode::SUCCESS;
334 uint8_t totSlice = 3 * numLut + numFadc;
337 for (
int asic = 0 ; asic < 4 ; ++asic ) {
338 for (
int mcm = 0 ; mcm < 16 ; ++mcm ) {
340 std::vector<uint32_t> rotated(totSlice);
342 for ( uint8_t slice = 0 ; slice < totSlice ; ++slice ) {
343 for ( uint8_t bit = 0 ; bit < 11 ; ++bit ) {
344 if ( state.
m_ppBlock[slice * 11 + asic * (11 * totSlice) + bit + 1] & (1 << mcm))
345 rotated[slice] |= (1 << bit);
349 bool nonZeroData =
false;
350 for (uint8_t slice = 0; slice < numLut; ++slice) {
352 || rotated[slice + numLut]
353 || rotated[slice + 2 * numLut + numFadc]) {
359 std::vector<uint8_t> lcpVal;
360 std::vector<uint8_t> lcpBcidVec;
361 std::vector<uint8_t> ljeVal;
362 std::vector<uint8_t> ljeSat80Vec;
363 std::vector<int16_t> pedCor;
364 std::vector<uint8_t> pedEn;
366 std::vector<uint16_t> adcVal;
367 std::vector<uint8_t> adcExt;
370 for (uint8_t slice = 0; slice < numLut; ++slice) {
371 lcpVal.push_back(rotated[slice] & 0xff);
372 ljeVal.push_back(rotated[slice + numLut] & 0xff);
373 pedCor.push_back(::pedCorrection(rotated[slice + 2 * numLut + numFadc] & 0x3ff));
375 lcpBcidVec.push_back((rotated[slice] >> 8) & 0x7);
376 ljeSat80Vec.push_back((rotated[slice + numLut] >> 8) & 0x7);
377 pedEn.push_back((rotated[slice + 2 * numLut + numFadc] >> 10) & 0x1);
381 for (uint8_t slice = 0; slice < numFadc; ++slice) {
382 if (rotated[slice + numLut]) {
389 for (uint8_t slice = 0; slice < numFadc; ++ slice) {
390 adcVal.push_back(rotated[slice + 2 * numLut] & 0x3ff);
391 adcExt.push_back((rotated[slice + 2 * numLut] >> 10 & 0x1) & 0x3ff);
401 std::move(lcpBcidVec),
403 std::move(ljeSat80Vec),
412 return StatusCode::SUCCESS;
423 present = br.getField(1);
433 std::vector<uint16_t> adcVal = {0 , 0, 0, 0, 0};
434 std::vector<uint8_t> adcExt = {0 , 0, 0, 0, 0};
436 uint8_t minHeader = br.getField(4);
437 uint8_t minIndex = minHeader % 5;
438 if (minHeader < 15) {
439 if (minHeader < 10) {
442 fmt = 2 + br.getField( 2);
443 uint8_t haveLut = br.getField(1);
446 lutVal = br.getField(3);
450 uint8_t haveExt = br.getField(1);
452 lutVal = br.getField(8);
453 lutExt = br.getField(1);
454 lutSat = br.getField(1);
455 lutPeak = br.getField(1);
459 for(uint8_t i = 0; i < 5; ++i) {
460 adcExt[i] = br.getField(1);
469 uint8_t haveAdc = br.getField(1);
471 uint16_t val = br.getField(10);
472 for(uint8_t i = 0; i < 5; ++i) {
484 std::vector<uint8_t> {lutVal},
485 std::vector<uint8_t> {uint8_t(lutExt | (lutSat << 1) | (lutPeak << 2))},
492 }
catch (
const std::out_of_range& ex) {
496 return StatusCode::SUCCESS;
501 BitReader& br, uint8_t format, uint8_t minIndex)
const
503 std::vector<uint16_t> adc = {0, 0, 0, 0, 0};
506 for(uint8_t i = 0; i <5; ++i) {
507 uint8_t longField = 0;
510 longField = br.getField(1);
511 numBits = longField == 0? 4: (format * 2);
513 numBits = i == 0? 4: (format + 2);
517 minAdc = br.getField(numBits);
518 if (longField == 0) {
522 adc[i] = minAdc + br.getField(numBits);
529 adc[0] = adc[minIndex];
530 adc[minIndex] = minAdc;
542 StatusCode
sc = StatusCode::SUCCESS;
549 const uint8_t nTotal = numAdc + numLut;
550 const uint8_t wordsPerBlock = 8;
551 const uint8_t iBlk = inData / wordsPerBlock;
555 for(uint8_t i = 0; i < 2; ++i) {
556 uint16_t subword = (word >> 16 * i) & 0x7ff;
557 state.
m_ppLuts[iChan].push_back(subword);
560 }
else if (iBlk < nTotal) {
561 for(uint8_t i = 0; i < 2; ++i) {
562 uint16_t subword = (word >> (16 * i)) & 0x7ff;
563 state.
m_ppFadcs[iChan].push_back(subword);
569 sc = StatusCode::FAILURE;
580 return StatusCode::SUCCESS;
583 return StatusCode::SUCCESS;
585 return StatusCode::FAILURE;
593 int16_t pedCorBase = -20;
597 for(uint8_t chan = 0; chan <
s_channels; ++chan) {
600 std::vector<uint8_t> haveLut(numLut, 0);
601 std::vector<uint8_t> lcpVal(numLut, 0);
603 std::vector<uint8_t> lcpExt(numLut, 0);
604 std::vector<uint8_t> lcpSat(numLut, 0);
605 std::vector<uint8_t> lcpPeak(numLut, 0);
606 std::vector<uint8_t> lcpBcidVec(numLut, 0);
608 std::vector<uint8_t> ljeVal(numLut, 0);
610 std::vector<uint8_t> ljeLow(numLut, 0);
611 std::vector<uint8_t> ljeHigh(numLut, 0);
612 std::vector<uint8_t> ljeRes(numLut, 0);
613 std::vector<uint8_t> ljeSat80Vec(numLut, 0);
615 std::vector<uint16_t> adcVal(numAdc, 0);
616 std::vector<uint8_t> adcExt(numAdc, 0);
617 std::vector<int16_t> pedCor(numLut, 0);
618 std::vector<uint8_t> pedEn(numLut, 0);
620 int8_t encoding = -1;
621 int8_t minIndex = -1;
624 present = br.getField(1);
628 CHECK((encoding != -1) && (minIndex != -1));
632 for(
uint i=0; i < numLut; ++i) {
633 lcpPeak[i] = br.getField(1);
637 for (uint8_t i = 0; i < numLut; ++i) {
638 ljeLow[i] = br.getField(1);
644 for (uint8_t i = 0; i < numLut; ++i) {
645 if (lcpPeak[i] == 1) {
646 lcpVal[i] = br.getField(4);
649 for(uint8_t i = 0; i < numLut; ++i) {
650 if (lcpPeak[i] == 1){
651 ljeVal[i] = br.getField(3);
655 }
else if (encoding < 6) {
657 for(uint8_t i = 0; i < numLut; ++i){
658 haveLut[i] = br.getField(1);
662 uint8_t haveExt = br.getField(1);
665 for (uint8_t i = 0; i < numAdc; ++i) {
666 adcExt[i] = br.getField(1);
670 for(uint8_t i = 0; i < numLut; ++i){
671 if (haveLut[i] == 1) {
672 lcpVal[i] = br.getField(8);
673 lcpExt[i] = br.getField(1);
674 lcpSat[i] = br.getField(1);
675 lcpPeak[i] = br.getField(1);
679 for(uint8_t i = 0; i < numLut; ++i){
680 if (haveLut[i] == 1) {
681 ljeVal[i] = br.getField(8);
682 ljeLow[i] = br.getField(1);
683 ljeHigh[i] = br.getField(1);
684 ljeRes[i] = br.getField(1);
692 if (minIndex <0)
return StatusCode::FAILURE;
695 if ((encoding < 3) || (encoding == 6)) {
696 for (uint8_t i = 0; i < numLut; ++i)
698 pedCor[i] = br.getField(6) + pedCorBase;
707 for (uint8_t i = 0; i < numLut; ++i)
709 uint16_t val = br.getField(10);
710 pedCor[i] = ::pedCorrection(val);
711 pedEn[i] = br.getField(1);
715 for(uint8_t i=0; i < numLut; ++i){
716 lcpBcidVec[i] = uint8_t((lcpPeak[i] << 2) | (lcpSat[i] << 1) | lcpExt[i]);
717 ljeSat80Vec[i] = uint8_t((ljeRes[i] << 2) | (ljeHigh[i] << 1) | ljeLow[i]);
722 std::move(lcpVal), std::move(lcpBcidVec),
723 std::move(ljeVal), std::move(ljeSat80Vec),
724 std::move(adcVal), std::move(adcExt),
725 std::move(pedCor), std::move(pedEn)));
730 }
catch (
const std::out_of_range& ex) {
735 return StatusCode::SUCCESS;
741 int8_t& encoding, int8_t& minIndex)
const
743 uint8_t minHeader = 0;
746 minHeader = br.getField(4);
748 minIndex = minHeader % 5;
750 if (minHeader < 10) {
751 encoding = minHeader / 5;
753 encoding = 2 + br.getField(2);
762 }
else if (numAdc == 7) {
764 }
else if (numAdc < 16) {
769 uint8_t fieldSize = 1 << numBits;
770 minHeader = br.getField(numBits);
771 uint8_t encValue = fieldSize - 1;
772 if (minHeader == encValue) {
776 minHeader += br.getField(2) << numBits;
777 minIndex = minHeader % fieldSize;
778 encValue = 3 * fieldSize;
780 if (minHeader < encValue) {
781 encoding = minHeader / fieldSize;
783 encoding = 3 + br.getField(2);
793 uint8_t encoding, uint8_t minIndex)
const
798 uint16_t val = br.getField(6);
799 return std::vector<uint16_t>(numAdc, val);
800 }
else if ( encoding < 3) {
801 std::vector<uint16_t> adc(numAdc, 0);
803 adc[minIndex] = minAdc;
804 for(uint8_t i = 1; i < numAdc; ++i) {
805 adc[i == minIndex? 0: i] = br.getField(encoding + 2) + minAdc;
809 std::vector<uint16_t> adc(numAdc, 0);
810 uint16_t minAdc = br.getField(1)
811 ? br.getField(encoding * 2)
815 adc[minIndex] = minAdc;
816 for (uint8_t i = 1; i < numAdc; ++i) {
817 adc[minIndex == i? 0: i] = br.getField(
818 br.getField(1)? encoding * 2: 4
829 return StatusCode::SUCCESS;
832 return StatusCode::FAILURE;
834 return StatusCode::FAILURE;
845 for (uint8_t chan = 0; chan < 64; ++chan) {
848 std::vector<uint8_t> lcpVal;
849 std::vector<uint8_t> lcpBcidVec;
851 std::vector<uint8_t> ljeVal;
852 std::vector<uint8_t> ljeSat80Vec;
856 std::vector<uint16_t> adcVal;
857 std::vector<uint8_t> adcExt;
858 std::vector<int16_t> pedCor;
859 std::vector<uint8_t> pedEn;
861 for (
int i = 0; i < numLut; ++i) {
862 lcpVal.push_back(br.getField(8));
863 lcpBcidVec.push_back(br.getField(3));
866 for (
int i = 0; i < numLut; ++i) {
867 ljeVal.push_back(br.getField(8));
868 ljeSat80Vec.push_back(br.getField(3));
871 for (
int i = 0; i < numAdc; ++i) {
872 adcVal.push_back(br.getField(10));
873 adcExt.push_back(br.getField(1));
876 for (
int i = 0; i < numLut; ++i) {
877 uint16_t pc = br.getField(10);
878 pedCor.push_back(pedCorrection(pc));
879 pedEn.push_back(br.getField(1));
881 }
catch (
const std::out_of_range& ex) {
888 std::move(lcpVal), std::move(lcpBcidVec),
889 std::move(ljeVal), std::move(ljeSat80Vec),
890 std::move(adcVal), std::move(adcExt),
891 std::move(pedCor), std::move(pedEn)));
894 return StatusCode::SUCCESS;
899 for(
const auto & lut : state.
m_ppLuts) {
908 return StatusCode::SUCCESS;
912 uint8_t crate, uint8_t module, uint32_t payload)
const
920 if (tt->coolId() >> 16 & crateModuleMask(crate, module)){
923 tt->setErrorWord( errorBits.
error() );
932 uint8_t crate, uint8_t module,
BitReader& br)
const
936 uint8_t haveStatus = br.getField(1);
937 uint8_t haveErrors = br.getField(1);
940 if (haveStatus || haveErrors) {
943 uint16_t errorWord = 0;
948 if ((mcmMap & (1 << i)) != 0) {
949 uint16_t blockStatus = 0;
950 uint16_t blockErrors = 0;
953 blockStatus = br.getField(5);
954 errorWord |= blockStatus;
957 blockErrors = br.getField(6);
958 errorWord |= (blockErrors<<5);
961 mcmErrors.at(i)=errorWord;
970 if (tt->coolId() >> 16 & crateModuleMask(crate, module)){
971 uint16_t mcmID = (tt->coolId() >> 8) & 0xff;
972 uint16_t chnID = tt->coolId() & 0xff;
973 uint16_t
error = mcmErrors.at(mcmID);
987 tt->setErrorWord( errorBits.
error() );
1001 std::vector<uint8_t>&& lcpVal,
1002 std::vector<uint8_t>&& lcpBcidVec,
1003 std::vector<uint8_t>&& ljeVal,
1004 std::vector<uint8_t>&& ljeSat80Vec,
1005 std::vector<uint16_t>&& adcVal,
1006 std::vector<uint8_t>&& adcExt,
1007 std::vector<int16_t>&& pedCor,
1008 std::vector<uint8_t>&& pedEn)
const
1010 uint32_t coolId = ::coolId(crate, module, channel);
1016 bool isData =
m_ppmMaps->mapping(crate, module, channel,
eta,
phi, layer);
1019 return StatusCode::SUCCESS;
1023 const int pin = channel % 16;
1024 const int asic = channel / 16;
1025 eta = 16 * crate + module;
1026 phi = 4 * pin + asic;
1032 tt->initialize(coolId,
eta,
phi,
1033 std::move(lcpVal), std::move(ljeVal),
1034 std::move(pedCor), std::move(pedEn),
1035 std::move(lcpBcidVec), std::move(adcVal),
1036 std::move(adcExt), std::move(ljeSat80Vec),
1039 return StatusCode::SUCCESS;
1047 std::vector<uint8_t>&& luts,
1048 std::vector<uint8_t>&& lcpBcidVec,
1049 std::vector<uint16_t>&& fadc,
1050 std::vector<uint8_t>&& bcidExt
1053 std::vector<uint8_t> ljeSat80Vec;
1055 std::vector<int16_t> pedCor;
1056 std::vector<uint8_t> pedEn;
1057 std::vector<uint8_t> luts_copy =luts;
1060 crate, module, channel,
1061 std::move(luts), std::move(lcpBcidVec),
1062 std::move(luts_copy) , std::move(ljeSat80Vec),
1063 std::move(fadc), std::move(bcidExt),
1064 std::move(pedCor), std::move(pedEn))
1067 return StatusCode::SUCCESS;
1075 const std::vector<uint16_t>& luts,
1076 const std::vector<uint16_t>& fadc
1079 std::vector<uint8_t> lcpVal;
1080 std::vector<uint8_t> lcpBcidVec;
1082 std::vector<uint16_t> adcVal;
1083 std::vector<uint8_t> adcExt;
1085 for(
auto lut: luts) {
1096 crate, module, channel,
1097 std::move(lcpVal), std::move(lcpBcidVec),
1098 std::move(adcVal), std::move(adcExt)));
1100 return StatusCode::SUCCESS;
1108 const int crates = 8;
1114 for (
int crate = 0; crate < crates; ++crate) {
1115 for (
int slink = 0; slink <
m_srcIdMap->maxSlinks(); ++slink) {
1116 const uint32_t rodId =
m_srcIdMap->getRodID(crate, slink, 0,
1117 eformat::TDAQ_CALO_PREPROC);
1118 const uint32_t robId =
m_srcIdMap->getRobID(rodId);
1120 if (crate > 1 && crate < 6) {
1122 if (crate < 4 && slink == 0) {
1134 const std::string& sgKey)
const
1139 if (sgKey.find(
"Muon") != std::string::npos) {
1141 }
else if (sgKey.find(
"Spare") != std::string::npos) {
1159 (
const uint8_t numBits)
1167 if ((iBit + numBits) <= 31) {
1170 uint8_t nb1 = 31 - iBit;
1171 uint8_t nb2 = numBits - nb1;
1172 uint32_t field1 = ::bitFieldSize(
m_ppBlock[iWord], iBit, nb1);
1173 uint32_t field2 = ::bitFieldSize(
m_ppBlock[iWord + 1], 0, nb2);
1174 result = field1 | (field2 << nb1);
1180 throw std::out_of_range(
"Requested too much bits from ppm block");
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Atomic min/max functions.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
size_type capacity() const noexcept
Returns the total number of elements that the collection can hold before needing to allocate more mem...
std::vector< const ROBF * > VROBFRAG
T get(const uint32_t &word) const
This class provides conversion between Lower level Source ID to higher level source ID for L1Calo Byt...
int error() const
Return the full error word.
void set(ErrorBit bit, int value=1)
Set an error bit or data.
static const std::string xAODTriggerTowerLocation
T atomic_fetch_max(std::atomic< T > *a, T v, std::memory_order memorder=std::memory_order_seq_cst)
Atomically calculate maximum.
TriggerTowerContainer_v2 TriggerTowerContainer
Define the latest version of the TriggerTower container.
setScaleOne setStatusOne setSaturated int16_t
TriggerTower_v2 TriggerTower
Define the latest version of the TriggerTower class.