|
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"
39 static const InterfaceID IID_ICpByteStreamTool(
"CpByteStreamTool", 1, 1);
43 return IID_ICpByteStreamTool;
49 const std::string&
name,
52 m_cpmMaps(
"LVL1::CpmMappingTool/CpmMappingTool"),
53 m_errorTool(
"LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
54 m_channels(80), m_crates(4), m_modules(14),
55 m_subDetector(
eformat::TDAQ_CALO_CLUSTER_PROC_DAQ)
57 declareInterface<CpByteStreamTool>(
this);
60 "Crate/Module/Channel to Eta/Phi/Layer mapping tool");
63 "Offset of CP crate numbers in bytestream");
65 "Offset of CP crate numbers in RDOs");
69 "ROB fragment source identifiers");
73 "Format version number in sub-block header");
75 "Format identifier (0-1) in sub-block header");
77 "The number of S-Links per crate");
79 "The number of slices in the simulation");
81 "If >0, the number of slices in bytestream");
102 return StatusCode::SUCCESS;
108 const std::string& sgKey,
119 const std::string& sgKey,
130 const std::string& sgKey,
178 int timeslicesNew = 1;
180 for (
int crate=0; crate <
m_crates; ++crate) {
189 if (
mod%modulesPerSlink == 0) {
190 const int daqOrRoi = 0;
191 const int slink = (
m_slinks == 2) ? 2*(
mod/modulesPerSlink)
192 :
mod/modulesPerSlink;
194 msg() <<
"Treating crate " << hwCrate
195 <<
" slink " << slink <<
endmsg;
206 msg(MSG::ERROR) <<
"Inconsistent number of slices or "
207 <<
"triggered slice offsets in data for crate "
208 << hwCrate <<
" slink " << slink <<
endmsg;
209 return StatusCode::FAILURE;
216 <<
"Slices/offset: " << timeslices <<
" " << trigCpm;
217 if (timeslices != timeslicesNew) {
218 msg() <<
" modified to " << timeslicesNew <<
" " << trigCpmNew;
223 userHeader.
setCpm(trigCpmNew);
227 theROD->push_back(userHeader.
header());
239 hwCrate,
module, timeslicesNew);
241 if (neutralFormat)
break;
252 const unsigned int key = towerKey.
ttKey(phi, eta);
255 std::vector<int> emData;
256 std::vector<int> hadData;
257 std::vector<int> emError;
258 std::vector<int> hadError;
272 const int index = ( neutralFormat ) ? 0 :
slice;
275 hadData[
slice], emErr, hadErr);
285 std::vector<unsigned int> vec0;
286 std::vector<unsigned int> vec1;
290 const int index = ( neutralFormat ) ? 0 :
slice;
301 if ( !subBlock->
pack()) {
302 msg(MSG::ERROR) <<
"CPM sub-block packing failed" <<
endmsg;
303 return StatusCode::FAILURE;
306 msg() <<
"CPM sub-block data words: "
309 subBlock->
write(theROD);
335 if (neutralFormat)
break;
341 for (
int dataID = 1; dataID < maxDataID; ++dataID) {
368 std::vector<unsigned int> hits0;
369 std::vector<unsigned int> hits1;
370 std::vector<int> err0;
371 std::vector<int> err1;
379 const int index = ( neutralFormat ) ? 0 :
slice;
383 subBlock = cmmHit1Blocks[
index];
390 for (;
cos != cmmHit0Blocks.
end(); ++
cos) {
392 if ( !subBlock->
pack()) {
393 msg(MSG::ERROR) <<
"CMM-Cp sub-block packing failed" <<
endmsg;
394 return StatusCode::FAILURE;
397 msg() <<
"CMM-Cp sub-block data words: "
400 subBlock->
write(theROD);
403 for (;
cos != cmmHit1Blocks.
end(); ++
cos) {
405 if ( !subBlock->
pack()) {
406 msg(MSG::ERROR) <<
"CMM-Cp sub-block packing failed" <<
endmsg;
407 return StatusCode::FAILURE;
410 msg() <<
"CMM-Cp sub-block data words: "
413 subBlock->
write(theROD);
417 return StatusCode::SUCCESS;
434 for (
int slink = 0; slink < maxSlinks; ++slink)
436 const int daqOrRoi = 0;
456 const std::string& sgKey,
463 const static std::string
flag(
"Overlap");
464 const std::string::size_type
pos = sgKey.find(
flag);
466 (
pos == std::string::npos ||
pos != sgKey.length() -
flag.length()) ? 0 : 1;
477 std::set<uint32_t> dupCheck;
480 for (; rob != robEnd; ++rob) {
484 msg() <<
"Treating ROB fragment " << robCount <<
endmsg;
489 uint32_t robid = (*rob)->source_id();
490 if ((*rob)->nstatus() > 0) {
492 (*rob)->status(robData);
495 if (
debug)
msg() <<
"ROB status error - skipping fragment" <<
endmsg;
502 if (!dupCheck.insert(robid).second) {
513 (*rob)->rod_data(payloadBeg);
514 payloadEnd = payloadBeg + (*rob)->rod_ndata();
522 const uint32_t sourceID = (*rob)->rod_source_id();
531 msg() <<
"Wrong source identifier in data: ROD "
532 << MSG::hex << sourceID <<
" ROB " << robid
539 msg() <<
"Treating crate " << rodCrate
550 const int minorVersion = (*rob)->rod_version() & 0xffff;
552 const int headerWords = userHeader.
words();
553 if (headerWords != 1) {
555 if (
debug)
msg() <<
"Unexpected number of user header words: "
559 for (
int i = 0;
i < headerWords; ++
i) ++
payload;
561 int trigCpm = userHeader.
cpm();
562 int trigCmm = userHeader.
cpCmm();
564 msg() <<
"Minor format version number: " << MSG::hex
565 << minorVersion << MSG::dec <<
endmsg
566 <<
"CPM triggered slice offset: " << trigCpm <<
endmsg
567 <<
"CMM triggered slice offset: " << trigCmm <<
endmsg;
569 if (trigCpm != trigCmm) {
570 const int newTrig = (trigCpm > trigCmm) ? trigCpm : trigCmm;
573 if (
debug)
msg() <<
"Changed both offsets to " << newTrig <<
endmsg;
579 while (
payload != payloadEnd) {
589 cmmCpSubBlock.
clear();
591 if (cmmCpSubBlock.
crate() != rodCrate) {
592 if (
debug)
msg() <<
"Inconsistent crate number in ROD source ID"
615 if (cpmSubBlock.
crate() != rodCrate) {
616 if (
debug)
msg() <<
"Inconsistent crate number in ROD source ID"
634 return StatusCode::SUCCESS;
646 const int hwCrate = subBlock->
crate();
650 const int timeslices = subBlock->
timeslices();
651 const int sliceNum = subBlock->
slice();
653 msg() <<
"CMM-CP: Crate " << hwCrate
655 <<
" Firmware " << firmware
656 <<
" Summing " << summing
657 <<
" Total slices " << timeslices
658 <<
" Slice " << sliceNum <<
endmsg;
660 if (timeslices <= trigCmm) {
661 if (
debug)
msg() <<
"Triggered CMM slice from header "
662 <<
"inconsistent with number of slices: "
663 << trigCmm <<
", " << timeslices <<
endmsg;
667 if (timeslices <= sliceNum) {
668 if (
debug)
msg() <<
"Total slices inconsistent with slice number: "
669 << timeslices <<
", " << sliceNum <<
endmsg;
677 msg() <<
"CMM-CP sub-block unpacking failed: " << errMsg <<
endmsg;
690 const int sliceBeg = ( neutralFormat ) ? 0 : sliceNum;
691 const int sliceEnd = ( neutralFormat ) ? timeslices : sliceNum + 1;
730 ld.hitsVec0.assign(timeslices, 0);
731 ld.hitsVec1.assign(timeslices, 0);
732 ld.errVec0.assign(timeslices, 0);
733 ld.errVec1.assign(timeslices, 0);
742 std::make_unique<LVL1::CMMCPHits>(swCrate, dataID,
ld.hitsVec0,
ld.hitsVec1,
743 ld.errVec0,
ld.errVec1, trigCmm);
744 const int key = crate*100 + dataID;
745 data.m_cmmHitsMap.insert(std::make_pair(
key, chp.get()));
746 data.m_cmmHitCollection->push_back(std::move(chp));
748 ld.hitsVec0 =
ch->HitsVec0();
749 ld.hitsVec1 =
ch->HitsVec1();
750 ld.errVec0 =
ch->ErrorVec0();
751 ld.errVec1 =
ch->ErrorVec1();
752 const int nsl =
ld.hitsVec0.size();
753 if (timeslices != nsl) {
754 if (
debug)
msg() <<
"Inconsistent number of slices in sub-blocks"
773 ch->addHits(
ld.hitsVec0,
ld.hitsVec1,
ld.errVec0,
ld.errVec1);
792 const int hwCrate = subBlock->
crate();
794 const int timeslices = subBlock->
timeslices();
795 const int sliceNum = subBlock->
slice();
797 msg() <<
"CPM: Crate " << hwCrate
799 <<
" Total slices " << timeslices
800 <<
" Slice " << sliceNum <<
endmsg;
807 if (timeslices <= trigCpm) {
808 if (
debug)
msg() <<
"Triggered CPM slice from header "
809 <<
"inconsistent with number of slices: "
810 << trigCpm <<
", " << timeslices <<
endmsg;
814 if (timeslices <= sliceNum) {
815 if (
debug)
msg() <<
"Total slices inconsistent with slice number: "
816 << timeslices <<
", " << sliceNum <<
endmsg;
824 msg() <<
"CPM sub-block unpacking failed: " << errMsg <<
endmsg;
835 const int ssError = dErr.
error();
838 const int sliceBeg = ( neutralFormat ) ? 0 : sliceNum;
839 const int sliceEnd = ( neutralFormat ) ? timeslices : sliceNum + 1;
853 int emErr1 = ssError;
858 emErr1 = emErrBits.
error();
860 int hadErr1 = ssError;
865 hadErr1 = hadErrBits.
error();
867 if (em || had || emErr1 || hadErr1) {
873 const unsigned int key =
ld.towerKey->ttKey(phi, eta);
876 ld.emVec.assign(timeslices, 0);
877 ld.hadVec.assign(timeslices, 0);
878 ld.emErrVec.assign(timeslices, 0);
879 ld.hadErrVec.assign(timeslices, 0);
885 std::make_unique<LVL1::CPMTower>(phi, eta,
ld.emVec,
ld.emErrVec,
886 ld.hadVec,
ld.hadErrVec, trigCpm);
887 tdata.
m_ttMap.insert(std::make_pair(
key, ttp.get()));
890 ld.emVec =
tt->emEnergyVec();
891 ld.hadVec =
tt->hadEnergyVec();
892 ld.emErrVec =
tt->emErrorVec();
893 ld.hadErrVec =
tt->hadErrorVec();
894 const int nsl =
ld.emVec.size();
895 if (timeslices != nsl) {
897 msg() <<
"Inconsistent number of slices in sub-blocks"
905 if (
debug)
msg() <<
"Duplicate data for slice "
914 tt->fill(
ld.emVec,
ld.emErrVec,
ld.hadVec,
ld.hadErrVec, trigCpm);
917 }
else if (
verbose && (em || had || emErr || hadErr)) {
918 msg(
MSG::VERBOSE) <<
"Non-zero data but no channel mapping for channel "
933 const unsigned int hits0 = subBlock->
hits0(
slice);
934 const unsigned int hits1 = subBlock->
hits1(
slice);
935 if (hits0 || hits1) {
938 ld.hitsVec0.assign(timeslices, 0);
939 ld.hitsVec1.assign(timeslices, 0);
943 std::make_unique<LVL1::CPMHits>(swCrate,
module,
ld.hitsVec0,
ld.hitsVec1, trigCpm);
947 ld.hitsVec0 =
ch->HitsVec0();
948 ld.hitsVec1 =
ch->HitsVec1();
949 const int nsl =
ld.hitsVec0.size();
950 if (timeslices != nsl) {
951 if (
debug)
msg() <<
"Inconsistent number of slices in sub-blocks"
963 ch->addHits(
ld.hitsVec0,
ld.hitsVec1);
982 ConstCpmTowerMap::const_iterator mapIter = ttMap.find(
key);
983 if (mapIter != ttMap.end())
return mapIter->second;
988 const unsigned int key)
const
990 CpmTowerMap::const_iterator mapIter =
data.m_ttMap.find(
key);
991 if (mapIter !=
data.m_ttMap.end())
return mapIter->second;
1002 ConstCpmHitsMap::const_iterator mapIter =
1004 if (mapIter != hitsMap.end())
return mapIter->second;
1009 const int crate,
const int module)
const
1011 CpmHitsMap::const_iterator mapIter =
1013 if (mapIter !=
data.m_hitsMap.end())
return mapIter->second;
1024 ConstCmmCpHitsMap::const_iterator mapIter = cmmHitsMap.find(crate*100 + dataID);
1025 if (mapIter != cmmHitsMap.end())
return mapIter->second;
1031 const int dataID)
const
1033 CmmCpHitsMap::const_iterator mapIter =
data.m_cmmHitsMap.find(crate*100 + dataID);
1034 if (mapIter !=
data.m_cmmHitsMap.end())
return mapIter->second;
1049 for (;
pos != pose; ++
pos) {
1051 const unsigned int key = towerKey.
ttKey(
tt->phi(),
tt->eta());
1052 ttMap.insert(std::make_pair(
key,
tt));
1060 const hitCollection,
1064 if (hitCollection) {
1067 for (;
pos != pose; ++
pos) {
1071 hitsMap.insert(std::make_pair(
key,
hits));
1079 const hitCollection,
1083 if (hitCollection) {
1086 for (;
pos != pose; ++
pos) {
1089 const int key = crate*100 +
hits->dataID();
1090 cmmHitsMap.insert(std::make_pair(
key,
hits));
1098 const int modulesPerSlink,
1114 const unsigned int key = towerKey.
ttKey(phi, eta);
1116 if ( !
tt )
continue;
1117 const int numdat = 4;
1118 std::vector<int> sums(numdat);
1119 std::vector<int> sizes(numdat);
1121 (
tt->emEnergyVec()).end(), 0);
1123 (
tt->hadEnergyVec()).end(), 0);
1125 (
tt->emErrorVec()).end(), 0);
1127 (
tt->hadErrorVec()).end(), 0);
1128 sizes[0] = (
tt->emEnergyVec()).
size();
1129 sizes[1] = (
tt->hadEnergyVec()).
size();
1130 sizes[2] = (
tt->emErrorVec()).
size();
1131 sizes[3] = (
tt->hadErrorVec()).
size();
1132 const int peak =
tt->peak();
1133 for (
int i = 0;
i < numdat; ++
i) {
1134 if (sums[
i] == 0)
continue;
1138 }
else if (
slices != sizes[
i] || trigC != peak)
return false;
1143 const int numdat = 2;
1144 std::vector<unsigned int> sums(numdat);
1145 std::vector<int> sizes(numdat);
1147 (
hits->HitsVec0()).end(), 0);
1149 (
hits->HitsVec1()).end(), 0);
1150 sizes[0] = (
hits->HitsVec0()).
size();
1151 sizes[1] = (
hits->HitsVec1()).
size();
1152 const int peak =
hits->peak();
1153 for (
int i = 0;
i < numdat; ++
i) {
1154 if (sums[
i] == 0)
continue;
1158 }
else if (
slices != sizes[
i] || trigC != peak)
return false;
1165 for (
int dataID = 0; dataID < maxDataID; ++dataID) {
1166 const int numdat = 4;
1167 std::vector<unsigned int> sums(numdat);
1168 std::vector<int> sizes(numdat);
1172 (
hits->HitsVec0()).end(), 0);
1174 (
hits->HitsVec1()).end(), 0);
1176 (
hits->ErrorVec0()).end(), 0);
1178 (
hits->ErrorVec1()).end(), 0);
1179 sizes[0] = (
hits->HitsVec0()).
size();
1180 sizes[1] = (
hits->HitsVec1()).
size();
1181 sizes[2] = (
hits->ErrorVec0()).
size();
1182 sizes[3] = (
hits->ErrorVec1()).
size();
1183 const int peak =
hits->peak();
1184 for (
int i = 0;
i < numdat; ++
i) {
1185 if (sums[
i] == 0)
continue;
1189 }
else if (
slices != sizes[
i] || trigC != peak)
return false;
int hadData(int slice, int channel) const
Return Had data for given channel.
static CmmFirmwareCode cmmType(uint32_t word)
CMM differentiation (CMM_CP, CMM_JET, or CMM_ENERGY)
char data[hepevt_bytes_allocation_ATLAS]
int slink(uint32_t code) const
Return slink from unpacked moduleID.
Const iterator class for DataVector/DataList.
bool anyTowerData(int channel) const
Return true if there is tower data for given channel.
int unpackErrorCode() const
Return the unpacking error code.
Template class for assembling a full atlas raw event from subfragments.
Cluster Processor container for writing bytestream.
Sub-Block class for CMM-CP data.
static int peak(int oldPeak, int oldSlices, int newSlices)
Return new triggered slice offset.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
unsigned int hits(int slice, int source) const
Return hit counts for given CPM or source ID.
void setHits(int slice, int source, unsigned int hits, int error)
Store hit counts for given CPM or source ID.
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
int emData(int slice, int channel) const
Return Em data for given channel.
void setCmmHeader(int version, int format, int slice, int crate, int summing, int firmware, int position, int timeslices)
Store CMM header.
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.
The CPMHits object contains the hit data produced by a given Cluster Processor Module,...
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.
int hitsError(int slice, int source) const
Return hit error for given CPM or source ID.
unsigned int hits0(int slice) const
Return e/gamma hit counts.
int hadError(int slice, int channel) const
Return Had error for given channel.
void setHits(int slice, unsigned int hit0, unsigned int hit1)
Store hit counts.
int timeslices() const
Return number of timeslices.
The CPMTower class contains the TriggerTower information received by the Cluster Processor Modules.
bool unpack()
Unpack data.
static void data(const std::vector< int > &oldVec, std::vector< int > &newVec, int newSlices)
Return modified data vector<int>
(Non-const) Iterator class for DataVector/DataList.
::StatusCode StatusCode
StatusCode definition for legacy code.
Summary of CP (EM/tau) hits received by the merger modules.
void set(ErrorBit bit, int value=1)
Set an error bit or data.
int crate(uint32_t code) const
Return crate from unpacked moduleID.
Sub-Block class for CPM data.
void clear()
Clear all data.
std::vector< const ROBF * > VROBFRAG
static SubBlockWordType wordType(uint32_t word)
Word identification.
int error() const
Return the full error word.
std::string unpackErrorMsg() const
Return the unpacking error message for printing.
unsigned int hits1(int slice) const
Return tau hit counts.
uint16_t minorVersion() const
Return ROD header minor version to use when writing BS.
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.
void clear()
Clear all data.
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.
void setRodMinorVersion(uint16_t m)
change the ROD minor version
void fillTowerData(int slice, int channel, int em, int had, int emErr, int hadErr)
Store trigger tower data.
uint32_t getRodID(int crate, int slink, int daqOrRoi, eformat::SubDetector subdet) const
Make a ROD Source ID.
int emError(int slice, int channel) const
Return Em error for given channel.
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.
int daqOrRoi(uint32_t code) const
Return daqOrRoi from unpacked moduleID.
void setCpmHeader(int version, int format, int slice, int crate, int module, int timeslices)
Store CPM header.
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
bool unpack()
Unpack data.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.