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