10 #include "GaudiKernel/IInterface.h"
11 #include "GaudiKernel/MsgStream.h"
12 #include "GaudiKernel/StatusCode.h"
43 static const InterfaceID IID_IPpmByteStreamV1Tool(
"PpmByteStreamV1Tool", 1, 1);
47 return IID_IPpmByteStreamV1Tool;
53 const std::string &
name,
56 m_ppmMaps(
"LVL1::PpmMappingTool/PpmMappingTool"),
57 m_errorTool(
"LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
58 m_sms(
"SegMemSvc/SegMemSvc",
name),
59 m_version(1), m_compVers(4),
60 m_subDetector(
eformat::TDAQ_CALO_PREPROC)
62 declareInterface<PpmByteStreamV1Tool>(
this);
65 "Crate/Module/Channel to Eta/Phi/Layer mapping tool");
67 "Tool to collect errors for monitoring");
70 "Print compressed format statistics");
72 "The number of S-Links per crate");
76 "Only make trigger towers with non-zero EM or Had energy");
78 "ROB fragment source identifiers");
80 "Pedestal value - needed for compressed formats 0,1 only");
84 "Format identifier (0-3) in sub-block header");
86 "FADC baseline lower bound for compressed formats");
88 "FADC threshold for super-compressed format");
90 "The number of LUT slices in the simulation");
92 "The number of FADC slices in the simulation");
94 "If >0, the number of LUT slices in bytestream");
96 "If >0, the number of FADC slices in bytestream");
98 "Minimum crate number, allows partial output");
100 "Maximum crate number, allows partial output");
121 return StatusCode::SUCCESS;
133 return StatusCode::SUCCESS;
140 const std::string& sgKey,
148 const std::string
flag(
"Spare");
149 const std::string::size_type
pos = sgKey.find(
flag);
151 (
pos != std::string::npos &&
pos == (sgKey.length() -
flag.length()));
152 const std::string flag2(
"Muon");
153 const std::string::size_type pos2 = sgKey.find(flag2);
155 (pos2 != std::string::npos && pos2 == (sgKey.length() - flag2.length()));
156 bool dataChannels = (!spareChannels && !muonChannels);
161 const int chanBitVecSize = maxChannels / 32;
164 std::lock_guard guard (
sd.m_mutex);
166 if (
sd.m_ttData.empty())
168 const int spareSize = maxChannels - 2 *
s_dataSize;
172 sd.m_ttSpare.reserve(spareSize);
173 sd.m_ttMuon.reserve(muonSize);
174 sd.m_ttPos.resize(maxChannels);
175 sd.m_chanLayer.resize(chanBitVecSize);
176 sd.m_dataChan.resize(chanBitVecSize);
177 sd.m_spareChan.resize(chanBitVecSize);
178 sd.m_muonChan.resize(chanBitVecSize);
179 sd.m_dataMod.resize(modBitVecSize);
180 sd.m_spareMod.resize(modBitVecSize);
181 sd.m_muonMod.resize(modBitVecSize);
184 std::vector<int> dummyS;
185 std::vector<int> dummyL(1);
186 std::vector<int> dummyF(5);
189 for (
int crate = 0; crate <
s_crates; ++crate)
194 const int word2 =
index2 / 32;
195 const int bit2 =
index2 % 32;
199 const int word =
index / 32;
200 const int bit =
index % 32;
204 unsigned int key = 0;
209 itt = ttMap.find(
key);
210 if (itt == ttMap.end())
215 dummyF, dummyL, dummyF, dummyL, 0, 0, 0,
216 dummyF, dummyL, dummyF, dummyL, 0, 0, 0);
217 sd.m_ttData.push_back(
tt);
218 const int count = dataCount++;
220 ttMap.insert(std::make_pair(
key,
count));
224 sd.m_ttPos[
index] = itt->second;
226 sd.m_chanLayer[word] |= (
layer << bit);
227 sd.m_dataChan[word] |= (1 << bit);
228 sd.m_dataMod[word2] |= (1 << bit2);
236 phi = 4 * pin + asic;
239 key = (crate << 24) | (
type << 20) | (
module << 16) | (pin << 8) | asic;
243 dummyF, dummyL, dummyF, dummyL, 0, 0, 0,
244 dummyS, dummyS, dummyS, dummyS, 0, 0, 0);
245 sd.m_ttSpare.push_back(
tt);
246 sd.m_ttPos[
index] = spareCount++;
247 sd.m_chanLayer[word] |= (
layer << bit);
248 sd.m_spareChan[word] |= (1 << bit);
249 sd.m_spareMod[word2] |= (1 << bit2);
250 if ((crate == 2 || crate == 3) && (
module == 0))
252 sd.m_ttMuon.push_back(
tt);
253 sd.m_muonChan[word] |= (1 << bit);
254 sd.m_muonMod[word2] |= (1 << bit2);
278 const int colSize = dataChannels ? 2 * ttCol.size()
280 sd.m_foundChan.assign(chanBitVecSize, 0);
284 std::vector<int> lut;
285 std::vector<int> fadc;
286 std::vector<int> bcidLut;
287 std::vector<int> bcidFadc;
294 std::set<uint32_t> dupCheck;
297 for (; rob != robEnd; ++rob)
303 msg() <<
"Treating ROB fragment " << robCount <<
endmsg;
308 uint32_t robid = (*rob)->source_id();
309 if ((*rob)->nstatus() > 0)
312 (*rob)->status(robData);
316 if (
debug)
msg() <<
"ROB status error - skipping fragment" <<
endmsg;
323 if (!dupCheck.insert(robid).second)
335 (*rob)->rod_data(payloadBeg);
336 payloadEnd = payloadBeg + (*rob)->rod_ndata();
345 const uint32_t sourceID = (*rob)->rod_source_id();
355 msg() <<
"Wrong source identifier in data: ROD "
356 << MSG::hex << sourceID <<
" ROB " << robid
363 const int minorVersion = (*rob)->rod_version() & 0xffff;
372 msg() <<
"Treating crate " << rodCrate
385 const int headerWords = userHeader.
words();
386 if (headerWords != 1)
391 msg() <<
"Unexpected number of user header words: "
396 for (
int i = 0;
i < headerWords; ++
i) ++
payload;
398 const int trigLut = userHeader.
ppmLut();
399 const int trigFadc = userHeader.
ppmFadc();
404 msg() <<
"Minor format version number: "
405 << MSG::hex << minorVersion << MSG::dec <<
endmsg
406 <<
"LUT triggered slice offset: " << trigLut <<
endmsg
407 <<
"FADC triggered slice offset: " << trigFadc <<
endmsg
408 <<
"FADC baseline lower bound: " << fadcBaseline <<
endmsg;
410 const int runNumber = (*rob)->rod_run_no() & 0xffffff;
414 int chanPerSubBlock = 0;
415 bool firstBlock =
false;
429 if (
sd.m_ppmBlocks.empty())
435 payloadFirst = subBlock->
read(
payload, payloadEnd);
437 if (chanPerSubBlock == 0)
440 if (
debug)
msg() <<
"Unsupported version/data format: "
445 if (
debug)
msg() <<
"Channels per sub-block: "
446 << chanPerSubBlock <<
endmsg;
450 if (
debug)
msg() <<
"ROB fragment contains user header only" <<
endmsg;
453 const int numSubBlocks =
s_channels / chanPerSubBlock;
454 const int size =
sd.m_ppmBlocks.size();
455 if (numSubBlocks >
size)
457 for (
int i =
size;
i < numSubBlocks; ++
i)
466 for (
int i = 0;
i < headerWords; ++
i) ++
payload;
476 for (
int block = 0; block < numSubBlocks; ++block)
492 msg() <<
"Unexpected channel sequence number: "
494 << block *chanPerSubBlock <<
endmsg;
513 crate = subBlock->
crate();
519 if (crate != rodCrate)
523 msg() <<
"Inconsistent crate number in ROD source ID" <<
endmsg;
531 if (subBlock->
crate() != crate)
533 if (
debug)
msg() <<
"Inconsistent crate number in sub-blocks"
540 if (
debug)
msg() <<
"Inconsistent module number in sub-blocks"
546 if (
payload == payloadEnd && block != numSubBlocks - 1)
557 bool isErrBlock =
false;
565 sd.m_errorBlock.clear();
568 if (
sd.m_errorBlock.crate() != crate)
570 if (
debug)
msg() <<
"Inconsistent crate number in error block"
575 if (
sd.m_errorBlock.module() !=
module)
577 if (
debug)
msg() <<
"Inconsistent module number in error block"
582 if (
sd.m_errorBlock.dataWords() && !
sd.m_errorBlock.unpack())
586 std::string errMsg(
sd.m_errorBlock.unpackErrorMsg());
587 msg() <<
"Unpacking error block failed: " << errMsg <<
endmsg;
589 rodErr =
sd.m_errorBlock.unpackErrorCode();
598 const int word2 =
index2 / 32;
599 const int bit2 =
index2 % 32;
600 if (!((colMod[word2] >> bit2) & 1))
continue;
604 for (
int block = 0; block < nPpmBlocks; ++block)
614 msg() <<
"Unpacking sub-block version/format/seqno: "
623 msg() <<
"Unpacking PPM sub-block failed: " << errMsg <<
endmsg;
631 const int channel = block * chanPerSubBlock +
chan;
633 const int word =
index / 32;
634 const int bit =
index % 32;
635 if (!((colChan[word] >> bit) & 1))
continue;
636 if (((
sd.m_foundChan[word] >> bit) & 1))
638 if (
debug)
msg() <<
"Duplicate data for crate/module/channel: "
649 if (lut.size() <
size_t(trigLut + 1))
653 msg() <<
"Triggered LUT slice from header "
654 <<
"inconsistent with number of slices: "
655 << trigLut <<
", " << lut.size() <<
endmsg;
660 if (fadc.size() <
size_t(trigFadc + 1))
664 msg() <<
"Triggered FADC slice from header "
665 <<
"inconsistent with number of slices: "
666 << trigFadc <<
", " << fadc.size() <<
endmsg;
677 sd.m_errorBlock.subStatus());
684 sd.m_ppmBlocks[nPpmBlocks - 1];
689 if (subBlock->
format() > 1 && subBlock->
seqno() < 4)
706 msg() << MSG::hex <<
error << MSG::dec <<
"/";
708 sd.m_foundChan[word] |= (1 << bit);
711 const int layer = ((
sd.m_chanLayer[word] >> bit) & 1);
714 tt->addEM(fadc, lut, bcidFadc, bcidLut,
error, trigLut, trigFadc);
718 tt->addHad(fadc, lut, bcidFadc, bcidLut,
error, trigLut, trigFadc);
731 if (ttCount != colSize)
735 msg() <<
"Found " << ttCount <<
" channels, expected " << colSize <<
endmsg;
737 std::vector<int>
dummy(1);
738 for (
int word = 0; word < chanBitVecSize; ++word)
740 if (
sd.m_foundChan[word] != colChan[word])
742 for (
int bit = 0; bit < 32; ++bit)
744 if (((
sd.m_foundChan[word] >> bit) & 1) != ((colChan[word] >> bit) & 1))
746 const int index = word * 32 + bit;
748 const int layer = ((
sd.m_chanLayer[word] >> bit) & 1);
753 else if (dataChannels)
769 for (; itr != itrE; ++itr)
771 if ((*itr)->emEnergy() || (dataChannels && (*itr)->hadEnergy()))
779 ttCollection->
assign(ttCol.begin(), ttCol.end());
782 return StatusCode::SUCCESS;
812 setupTTMaps(ttCollection, ttEmMap, ttHadMap, towerKey);
819 if (chanPerSubBlock == 0)
821 msg(MSG::ERROR) <<
"Unsupported version/data format: "
823 return StatusCode::FAILURE;
831 int slicesLutNew = 1;
832 int slicesFadcNew = 1;
843 if (
module % modulesPerSlink == 0)
845 const int daqOrRoi = 0;
846 const int slink =
module / modulesPerSlink;
849 msg() <<
"Treating crate " << crate <<
" slink " << slink <<
endmsg;
854 slicesLut, slicesFadc, trigLut, trigFadc,
858 msg(MSG::ERROR) <<
"Inconsistent number of slices or "
859 <<
"triggered slice offsets in data for crate "
860 << crate <<
" slink " << slink <<
endmsg;
861 return StatusCode::FAILURE;
871 <<
"LUT slices/offset: " << slicesLut <<
" " << trigLut;
872 if (slicesLut != slicesLutNew)
874 msg() <<
" modified to " << slicesLutNew <<
" " << trigLutNew;
877 <<
"FADC slices/offset: " << slicesFadc <<
" " << trigFadc;
878 if (slicesFadc != slicesFadcNew)
880 msg() <<
" modified to " << slicesFadcNew <<
" " << trigFadcNew;
891 theROD->push_back(userHeader.
header());
898 bool upstreamError =
false;
906 module, slicesFadcNew, slicesLutNew);
914 module, slicesFadcNew, slicesLutNew);
919 module, slicesFadcNew, slicesLutNew);
937 std::vector<int> lut;
938 std::vector<int> fadc;
939 std::vector<int> bcidLut;
940 std::vector<int> bcidFadc;
955 err =
tt->hadError();
967 if (errpp >> 2) upstreamError =
true;
970 if (
chan == chanPerSubBlock - 1)
973 if ( !subBlock.
pack())
975 msg(MSG::ERROR) <<
"PPM sub-block packing failed" <<
endmsg;
976 return StatusCode::FAILURE;
982 subBlock.
setStatus(0,
false,
false,
false,
false,
983 false,
false,
false);
986 msg() <<
"PPM sub-block data words: "
989 subBlock.
write(theROD);
994 bool glinkTimeout =
false;
995 bool daqOverflow =
false;
996 bool bcnMismatch =
false;
997 bool glinkParity =
false;
1000 glinkTimeout = errorBlock.
mcmAbsent() ||
1002 daqOverflow = errorBlock.
asicFull() ||
1012 daqOverflow = subBlock.
asicFull() ||
1018 subBlock.
setStatus(0, glinkTimeout,
false, upstreamError,
1019 daqOverflow, bcnMismatch,
false, glinkParity);
1022 msg() <<
"PPM sub-block data words: "
1025 subBlock.
write(theROD);
1029 if ( ! errorBlock.
pack())
1031 msg(MSG::ERROR) <<
"PPM error block packing failed" <<
endmsg;
1032 return StatusCode::FAILURE;
1034 errorBlock.
setStatus(0, glinkTimeout,
false, upstreamError,
1035 daqOverflow, bcnMismatch,
false, glinkParity);
1036 errorBlock.
write(theROD);
1039 msg() <<
"PPM error block data words: "
1053 return StatusCode::SUCCESS;
1060 if (
stats.empty())
return;
1062 for (
int i = 0;
i <
n; ++
i) {
1073 msg() <<
"Compression stats format/count: ";
1084 const double eta,
const double phi,
const int layer,
1091 TriggerTowerMapConst::const_iterator mapIter;
1094 mapIter = ttEmMap.find(
key);
1095 if (mapIter != ttEmMap.end())
tt = mapIter->second;
1099 mapIter = ttHadMap.find(
key);
1100 if (mapIter != ttHadMap.end())
tt = mapIter->second;
1119 for (;
pos != pose; ++
pos)
1122 const unsigned int key = towerKey.
ttKey(
tt->phi(),
tt->eta());
1127 accumulate((
tt->emBCIDvec()).begin(), (
tt->emBCIDvec()).end(), 0) ||
1128 accumulate((
tt->emBCIDext()).begin(), (
tt->emBCIDext()).end(), 0) ||
1131 ttEmMap.insert(std::make_pair(
key,
tt));
1134 if (
accumulate((
tt->hadLUT()).begin(), (
tt->hadLUT()).end(), 0) ||
1136 accumulate((
tt->hadBCIDvec()).begin(), (
tt->hadBCIDvec()).end(), 0) ||
1137 accumulate((
tt->hadBCIDext()).begin(), (
tt->hadBCIDext()).end(), 0) ||
1140 ttHadMap.insert(std::make_pair(
key,
tt));
1148 const int modulesPerSlink,
int &slicesLut,
int &slicesFadc,
1149 int &trigLut,
int &trigFadc,
1170 if ( !
tt )
continue;
1175 sliceL = (
tt->emLUT()).
size();
1176 sliceF = (
tt->emADC()).
size();
1177 trigL =
tt->emPeak();
1178 trigF =
tt->emADCPeak();
1182 if ((
tt->emLUT()).
size() != size_t(sliceL) ||
1183 (
tt->emADC()).
size() != size_t(sliceF) ||
1184 tt->emPeak() != trigL ||
tt->emADCPeak() != trigF)
1194 sliceL = (
tt->hadLUT()).
size();
1195 sliceF = (
tt->hadADC()).
size();
1196 trigL =
tt->hadPeak();
1197 trigF =
tt->hadADCPeak();
1201 if ((
tt->hadLUT()).
size() != size_t(sliceL) ||
1202 (
tt->hadADC()).
size() != size_t(sliceF) ||
1203 tt->hadPeak() != trigL ||
tt->hadADCPeak() != trigF)
1213 slicesFadc = sliceF;
1221 std::vector<uint32_t>
1224 std::vector<uint32_t> robIds;
1226 if (!spareChannels && !muonChannels) {
1230 if (robIds.empty()) {
1232 for (
int crate = 0; crate <
s_crates; ++crate)
1234 for (
int slink = 0; slink < maxlinks; ++slink)
1236 const int daqOrRoi = 0;
1241 if (spareChannels && !(crate > 1 && crate < 6)) {
1245 if (muonChannels && !(crate > 1 && crate < 4 && slink == 0)) {
1249 robIds.push_back (robId);
1257 const std::string &sgKey)
const
1260 const std::string
flag(
"Spare");
1261 const std::string::size_type
pos = sgKey.find(
flag);
1262 bool spareChannels =
1263 (
pos != std::string::npos &&
pos == (sgKey.length() -
flag.length()));
1265 const std::string flag2(
"Muon");
1266 const std::string::size_type pos2 = sgKey.find(flag2);
1268 (pos2 != std::string::npos && pos2 == (sgKey.length() - flag2.length()));
1270 if (spareChannels) {
1271 static const std::vector<uint32_t> sourceIDsSpare =
1273 return sourceIDsSpare;
1277 static const std::vector<uint32_t> sourceIDsMuon =
1279 return sourceIDsMuon;
1282 static const std::vector<uint32_t>
sourceIDs =
1291 std::vector<int>::const_iterator
pos;