Skip to content

Commit 1e6c1b7

Browse files
mfasDadavidrohr
authored andcommitted
[EMCAL-728] Reduce verbosity of the error logging
Errors related to raw channels (HW channels, DDL, cell ID are cached in a std::unordered_map. In case the same message has already been printed before the message is suppressed in all further occurrences and instead the number of occurrences is counted. In addition option to switch off merging of high gain/ low gain cells, this is particular of relevance for MC where only either of the two channel types are stored, resulting in a large amount of raw data errors.
1 parent e15ec5b commit 1e6c1b7

5 files changed

Lines changed: 369 additions & 166 deletions

File tree

Detectors/EMCAL/reconstruction/include/EMCALReconstruction/Channel.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,30 @@ class Channel
146146
/// \param starttime Start time of the bunch
147147
Bunch& createBunch(uint8_t bunchlength, uint8_t starttime);
148148

149+
/// \brief Extrcting hardware address from the channel header word
150+
/// \param channelheader Channel header word
151+
static int getHardwareAddressFromChannelHeader(int channelheader) { return channelheader & 0xFFF; };
152+
153+
/// \brief Extrcting payload size from the channel header word
154+
/// \param channelheader Channel header word
155+
static int getPayloadSizeFromChannelHeader(int channelheader) { return (channelheader >> 16) & 0x3FF; }
156+
157+
/// \brief Extracting branch index from the hardware address
158+
/// \param hwaddress Hardware address of the channel
159+
static int getBranchIndexFromHwAddress(int hwaddress) { return ((hwaddress >> 11) & 0x1); }
160+
161+
/// \brief Extracting FEC index in branch from the hardware address
162+
/// \param hwaddress Hardware address of the channel
163+
static int getFecIndexFromHwAddress(int hwaddress) { return ((hwaddress >> 7) & 0xF); }
164+
165+
/// \brief Extracting ALTRO index from the hardware address
166+
/// \param hwaddress Hardware address of the channel
167+
static int getAltroIndexFromHwAddress(int hwaddress) { return ((hwaddress >> 4) & 0x7); }
168+
169+
/// \brief Extracting Channel index in FEC from the hardware address
170+
/// \param hwaddress Hardware address of the channel
171+
static int getChannelIndexFromHwAddress(int hwaddress) { return (hwaddress & 0xF); }
172+
149173
private:
150174
int32_t mHardwareAddress = -1; ///< Hardware address
151175
uint8_t mPayloadSize = 0; ///< Payload size

Detectors/EMCAL/reconstruction/src/AltroDecoder.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void AltroDecoder::readChannels()
7070
}
7171
// starting a new channel
7272
auto channelheader = currentword;
73-
mChannels.emplace_back(currentword & 0xFFF, (currentword >> 16) & 0x3FF);
73+
mChannels.emplace_back(Channel::getHardwareAddressFromChannelHeader(currentword), Channel::getPayloadSizeFromChannelHeader(currentword));
7474
auto& currentchannel = mChannels.back();
7575
currentchannel.setBadChannel((currentword >> 29) & 0x1);
7676

Detectors/EMCAL/reconstruction/src/Channel.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,31 @@ int Channel::getBranchIndex() const
1717
if (mHardwareAddress == -1) {
1818
throw HardwareAddressError();
1919
}
20-
return ((mHardwareAddress >> 11) & 0x1);
20+
return getBranchIndexFromHwAddress(mHardwareAddress);
2121
}
2222

2323
int Channel::getFECIndex() const
2424
{
2525
if (mHardwareAddress == -1) {
2626
throw HardwareAddressError();
2727
}
28-
return ((mHardwareAddress >> 7) & 0xF);
28+
return getFecIndexFromHwAddress(mHardwareAddress);
2929
}
3030

3131
Int_t Channel::getAltroIndex() const
3232
{
3333
if (mHardwareAddress == -1) {
3434
throw HardwareAddressError();
3535
}
36-
return ((mHardwareAddress >> 4) & 0x7);
36+
return getAltroIndexFromHwAddress(mHardwareAddress);
3737
}
3838

3939
Int_t Channel::getChannelIndex() const
4040
{
4141
if (mHardwareAddress == -1) {
4242
throw HardwareAddressError();
4343
}
44-
return (mHardwareAddress & 0xF);
44+
return getChannelIndexFromHwAddress(mHardwareAddress);
4545
}
4646

4747
Bunch& Channel::createBunch(uint8_t bunchlength, uint8_t starttime)

Detectors/EMCAL/workflow/include/EMCALWorkflow/RawToCellConverterSpec.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
#include <climits>
13+
#include <string_view>
14+
#include <unordered_map>
1215
#include <vector>
16+
#include <boost/container_hash/hash.hpp>
1317

1418
#include "Framework/DataProcessorSpec.h"
1519
#include "Framework/Task.h"
1620
#include "DataFormatsEMCAL/Cell.h"
21+
#include "DataFormatsEMCAL/ErrorTypeFEE.h"
1722
#include "DataFormatsEMCAL/TriggerRecord.h"
1823
#include "Headers/DataHeader.h"
1924
#include "EMCALBase/Geometry.h"
@@ -81,6 +86,158 @@ class RawToCellConverterSpec : public framework::Task
8186
header::DataHeader::SubSpecificationType getSubspecification() const { return mSubspecification; }
8287

8388
private:
89+
/// \struct MessageChannel
90+
/// \brief Handling of messages per HW channel
91+
struct MessageChannel {
92+
int mDDL; ///< DDK ID
93+
int mFEC; ///< FEC in DDL
94+
int mHWAddress; ///< Full hardware address
95+
std::string mMessage; ///< Error message
96+
97+
/// \brief Check whehter message is equal to other message
98+
/// \param other Message to compare to
99+
/// \return True if the messages (including channel information) are the same, false otherwise
100+
bool operator==(const MessageChannel& other) const
101+
{
102+
return mDDL == other.mDDL && mFEC == other.mFEC && mHWAddress == other.mHWAddress && mMessage == other.mMessage;
103+
}
104+
105+
/// \brief Create combined error message with channel information
106+
/// \return Error message to be logged
107+
std::string print();
108+
};
109+
110+
/// \struct MessageChannelHasher
111+
/// \brief Hash functor for channel-based error messages
112+
struct MessageChannelHasher {
113+
114+
/// \brief Hash functor
115+
/// \param s MessageChannel object to be hashed
116+
/// \return Hash value
117+
size_t operator()(const MessageChannel& s) const
118+
{
119+
std::size_t seed = 0;
120+
boost::hash_combine(seed, s.mDDL);
121+
boost::hash_combine(seed, s.mFEC);
122+
boost::hash_combine(seed, s.mHWAddress);
123+
boost::hash_combine(seed, std::hash<std::string>{}(s.mMessage));
124+
return seed;
125+
}
126+
};
127+
128+
/// \struct MessageDDL
129+
/// \brief Handling messages per DDL
130+
struct MessageDDL {
131+
int mDDL; ///< DDL ID
132+
std::string mMessage; ///< Error message
133+
134+
/// \brief Check whehter message is equal to other message
135+
/// \param other Message to compare to
136+
/// \return True if the messages (including DDL information) are the same, false otherwise
137+
bool operator==(const MessageDDL& other) const
138+
{
139+
return mDDL == other.mDDL && mMessage == other.mMessage;
140+
}
141+
142+
/// \brief Create combined error message with DDL information
143+
/// \return Error message to be logged
144+
std::string print();
145+
};
146+
147+
/// \struct MessageDDLHasher
148+
/// \brief Hash functor for DDL-based error messages
149+
struct MessageDDLHasher {
150+
151+
/// \brief Hash functor
152+
/// \param s MessageDDL object to be hashed
153+
/// \return Hash value
154+
size_t operator()(const MessageDDL& s) const
155+
{
156+
std::size_t seed = 0;
157+
boost::hash_combine(seed, s.mDDL);
158+
boost::hash_combine(seed, std::hash<std::string>{}(s.mMessage));
159+
return seed;
160+
}
161+
};
162+
163+
/// \struct MessageCell
164+
/// \brief Handling messages per Cell
165+
struct MessageCell {
166+
int mSMID; ///< Supermodule ID
167+
int mCellID; ///< Cell ID
168+
std::string mMessage; ///< Error message
169+
170+
/// \brief Check whehter message is equal to other message
171+
/// \param other Message to compare to
172+
/// \return True if the messages (including cell information) are the same, false otherwise
173+
bool operator==(const MessageCell& other) const
174+
{
175+
return mSMID == other.mSMID && mCellID == other.mCellID && mMessage == other.mMessage;
176+
}
177+
178+
/// \brief Create combined error message with cell information
179+
/// \return Error message to be logged
180+
std::string print();
181+
};
182+
183+
/// \struct MessageCellHasher
184+
/// \brief Hash functor for Cell-based error messages
185+
struct MessageCellHasher {
186+
187+
/// \brief Hash functor
188+
/// \param s MessageDDL object to be hashed
189+
/// \return Hash value
190+
size_t operator()(const MessageCell& s) const
191+
{
192+
std::size_t seed = 0;
193+
boost::hash_combine(seed, s.mCellID);
194+
boost::hash_combine(seed, s.mSMID);
195+
boost::hash_combine(seed, std::hash<std::string>{}(s.mMessage));
196+
return seed;
197+
}
198+
};
199+
200+
/// \class MessageHandler
201+
/// \brief Logging of error message suppressing multiple occurrences
202+
///
203+
/// In order to prevent multiple occurrences of the same error message
204+
/// which can end up in a message flood on the infoBrowser an internal
205+
/// map keeps track of messages already printed before. In case the
206+
/// message is fouund in the map it is suppressed until the end of the run.
207+
template <typename MessageType, typename Hasher>
208+
class MessageHandler
209+
{
210+
public:
211+
/// \enum Severity
212+
/// \brief Logging severity
213+
enum class Severity {
214+
WARNING, ///< Waring level
215+
ERROR, ///< Error level
216+
FATAL ///< Fatal level
217+
};
218+
219+
/// \brief Constructor
220+
MessageHandler() = default;
221+
222+
/// \brief Destructor
223+
~MessageHandler() = default;
224+
225+
/// \brief Logging error message
226+
/// \brief msg Message object (channel and message)
227+
/// \brief level Log severity
228+
///
229+
/// Printing message in case the message has not been printed
230+
/// before for the same channel
231+
void log(MessageType msg, Severity level);
232+
233+
private:
234+
std::unordered_map<MessageType, unsigned long, Hasher> mErrorsPerEntry; ///< Counter of the number of suppressed error messages
235+
};
236+
237+
using ChannelMessageHandler = MessageHandler<MessageChannel, MessageChannelHasher>;
238+
using CellMessageHandler = MessageHandler<MessageCell, MessageCellHasher>;
239+
using DDLMessageHandler = MessageHandler<MessageDDL, MessageDDLHasher>;
240+
84241
/// \struct RecCellInfo
85242
/// \brief Internal bookkeeping for cell double counting
86243
///
@@ -101,21 +258,33 @@ class RawToCellConverterSpec : public framework::Task
101258
int mHWAddressLG; ///< HW address of LG (for monitoring)
102259
int mHWAddressHG; ///< HW address of HG (for monitoring)
103260
};
261+
262+
/// \brief Check if the timeframe is an empty timeframe (contains DEADBEEF message)
263+
/// \return True if the timeframe is a lost timeframe, false if it is OK
104264
bool isLostTimeframe(framework::ProcessingContext& ctx) const;
265+
266+
/// \brief Send data to output channels
267+
/// \param cells Container with cells from all events in the timeframe
268+
/// \param triggers Trigger records with ranges in cell container
269+
/// \param decodingErrors Container with raw decoding errors (not separated per event)
105270
void sendData(framework::ProcessingContext& ctx, const std::vector<o2::emcal::Cell>& cells, const std::vector<o2::emcal::TriggerRecord>& triggers, const std::vector<ErrorTypeFEE>& decodingErrors) const;
106271

107272
header::DataHeader::SubSpecificationType mSubspecification = 0; ///< Subspecification for output channels
108273
int mNoiseThreshold = 0; ///< Noise threshold in raw fit
109274
int mNumErrorMessages = 0; ///< Current number of error messages
110275
int mErrorMessagesSuppressed = 0; ///< Counter of suppressed error messages
111276
int mMaxErrorMessages = 100; ///< Max. number of error messages
277+
bool mMergeLGHG = true; ///< Merge low and high gain cells
112278
bool mPrintTrailer = false; ///< Print RCU trailer
113279
Geometry* mGeometry = nullptr; ///!<! Geometry pointer
114280
std::unique_ptr<MappingHandler> mMapper = nullptr; ///!<! Mapper
115281
std::unique_ptr<CaloRawFitter> mRawFitter; ///!<! Raw fitter
116282
std::vector<Cell> mOutputCells; ///< Container with output cells
117283
std::vector<TriggerRecord> mOutputTriggerRecords; ///< Container with output cells
118284
std::vector<ErrorTypeFEE> mOutputDecoderErrors; ///< Container with decoder errors
285+
ChannelMessageHandler mChannelMessages; ///< Handling of error message per Channel
286+
CellMessageHandler mCellMessages; ///< Handling of error message per Cell
287+
DDLMessageHandler mDDLMessages; ///< Handling of error messages per DDL
119288
};
120289

121290
/// \brief Creating DataProcessorSpec for the EMCAL Cell Converter Spec

0 commit comments

Comments
 (0)