|
ATLAS Offline Software
|
Go to the documentation of this file.
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;
208 key =
sd.m_towerKey.ttKey(phi, eta);
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);
235 eta = 16 * crate +
module;
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,
1090 const unsigned int key = towerKey.
ttKey(phi, eta);
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,
1166 eta, phi,
layer))
continue;
1168 eta, phi,
layer, ttEmMap, ttHadMap,
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;
JetConstituentVector::iterator iterator
void fillPpmError(int chan, int errorWord)
Store an error word corresponding to a data channel.
uint16_t minorVersionPreLS1() const
Return last ROD header minor version for pre-LS1 data.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
int slink(uint32_t code) const
Return slink from unpacked moduleID.
bool timeout(int chan) const
Const iterator class for DataVector/DataList.
int unpackErrorCode() const
Return the unpacking error code.
Template class for assembling a full atlas raw event from subfragments.
static int peak(int oldPeak, int oldSlices, int newSlices)
Return new triggered slice offset.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
static bool cmmBlock(uint32_t word)
Determine if header word corresponds to CMM.
void write(FullEventAssembler< L1CaloSrcIdMap >::RODDATA *theROD) const
Output complete packed sub-block to ROD vector.
bool msgLvl(const MSG::Level lvl) const
uint32_t getRobID(uint32_t rod_id) const
Make a ROB Source ID from a ROD source ID.
void setRunNumber(int run)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType read(const OFFLINE_FRAGMENTS_NAMESPACE::PointerType beg, const OFFLINE_FRAGMENTS_NAMESPACE::PointerType end)
Input complete packed sub-block from ROD array.
std::vector< size_t > vec
constexpr auto lut(Generator &&f)
void assign(InputIterator first, InputIterator last)
Assign from iterators.
void setPedestal(int pedval)
void setPpmErrorHeader(int version, int format, int crate, int module, int slicesFadc, int slicesLut)
Store PPM error block header.
int ppmError(int chan) const
Return the error word for a data channel.
static void data(const std::vector< int > &oldVec, std::vector< int > &newVec, int newSlices)
Return modified data vector<int>
bool bunchMismatch(int chan) const
::StatusCode StatusCode
StatusCode definition for legacy code.
void set(ErrorBit bit, int value=1)
Set an error bit or data.
int crate(uint32_t code) const
Return crate from unpacked moduleID.
bool mcmAbsent(int chan) const
std::vector< const ROBF * > VROBFRAG
const std::vector< uint32_t > & compStats() const
Return reference to compression stats.
bool asicFull(int chan) const
static SubBlockWordType wordType(uint32_t word)
Word identification.
int error() const
Return the full error word.
bool eventMismatch(int chan) const
void setPpmHeader(int version, int format, int seqno, int crate, int module, int slicesFadc, int slicesLut)
Store PPM header.
std::string unpackErrorMsg() const
Return the unpacking error message for printing.
Sub-Block class for PPM data.
void clear()
Clear internal stack.
Trigger towers are the inputs to all other parts of the calorimeter trigger.
void clear()
Clear all data.
void setFadcOffset(int offset)
int channelsPerSubBlock(int version, int format)
Return the number of channels per sub-block.
int dataWords() const
Return number of data words.
uint32_t subStatus() const
Return Sub-status word.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
static bool errorBlock(uint32_t word)
Check if a header word is for an error block.
void setLutOffset(int offset)
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
eformat::SubDetector subDet(uint32_t code) const
Return sub-detector for given ID.
bool glinkPinParity(int chan) const
bool fpgaCorrupt(int chan) const
void setRodMinorVersion(uint16_t m)
change the ROD minor version
void setFadcThreshold(int threshold)
const boost::regex re(r_e)
void ppmData(int chan, std::vector< int > &lut, std::vector< int > &fadc, std::vector< int > &bcidLut, std::vector< int > &bcidFadc)
Return unpacked data for given channel.
bool unpack()
Unpack data.
uint32_t getRodID(int crate, int slink, int daqOrRoi, eformat::SubDetector subdet) const
Make a ROD Source ID.
void fillPpmData(int chan, const std::vector< int > &lut, const std::vector< int > &fadc, const std::vector< int > &bcidLut, const std::vector< int > &bcidFadc)
Store PPM data for later packing.
std::vector< uint32_t > RODDATA
ROD data as a vector of unsigned int.
int get(ErrorBit bit) const
Return an error bit or data.
virtual unsigned int ttKey(const TriggerTower &tower)
returns the key of the passed tower
int maxSlinks() const
Return the maximum possible number of slinks.
Define macros for attributes used to control the static checker.
void setStatus(uint32_t failingBCN, bool glinkTimeout, bool glinkDown, bool upstreamError, bool daqOverflow, bool bcnMismatch, bool glinkProtocol, bool glinkParity)
Store error status trailer.
int daqOrRoi(uint32_t code) const
Return daqOrRoi from unpacked moduleID.
The TriggerTowerKey object provides the key for each trigger tower depending on its eta-phi coords.
RODDATA * getRodData(uint32_t id)
get a block of ROD data
void setFadcBaseline(int baseline)
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
void fill(RawEventWrite *re, MsgStream &log)
Fill the FullEventFragment with all the ROD data stored in this.
TriggerTower_v2 TriggerTower
Define the latest version of the TriggerTower class.