Skip to content

Commit 26bc350

Browse files
aferrero2707ktf
authored andcommitted
[MCH] added error handler in raw decoder
The raw decoder handlers are now grouped in a structure, so that new handlers can be easily added in future if needed. A backward-compatible version of the createPageDecoder has been introduced, to be removed once all code using the O2 decoder will be adapted to use the RawDecoderHandlers structure. Currently handlers for SAMPA data packets and for decoder errors are implemented in the code. The DataDecoder algorithm is also moved into a separate source file, for better readability and easier unit testing. Some initial unit tests for the error handling in the User Logic decoder have been added.
1 parent 36fb134 commit 26bc350

19 files changed

+753
-290
lines changed

Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaCluster.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ struct SampaCluster {
6767
/// needed to store this cluster
6868
uint16_t nof10BitWords() const;
6969

70+
/// sum returns the total charge in the cluster
71+
uint32_t sum() const;
72+
7073
uint10_t sampaTime; //< 10 bits for a local time stamp
7174
uint20_t bunchCrossing; //< 20 bits for bunch crossing counter
7275
uint20_t chargeSum; //< 20 bits for a cluster sum

Detectors/MUON/MCH/Raw/Common/src/SampaCluster.cxx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,25 @@ uint16_t SampaCluster::nof10BitWords() const
6565
if (isClusterSum()) {
6666
n10 += 2; // 20 bits (chargesum)
6767
} else {
68-
for (auto s : samples) {
69-
++n10; // 10 bits for each sample
70-
}
68+
n10 += samples.size();
7169
}
7270
return n10;
7371
}
7472

73+
uint32_t SampaCluster::sum() const
74+
{
75+
uint32_t tot(0);
76+
if (isClusterSum()) {
77+
tot = chargeSum;
78+
} else {
79+
for (const auto& s : samples) {
80+
tot += s;
81+
}
82+
}
83+
84+
return tot;
85+
}
86+
7587
std::ostream& operator<<(std::ostream& os, const SampaCluster& sc)
7688
{
7789
os << fmt::format("ts {:4d} ", sc.sampaTime);

Detectors/MUON/MCH/Raw/Decoder/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
# submit itself to any jurisdiction.
1010

1111
o2_add_library(MCHRawDecoder
12-
SOURCES src/PageDecoder.cxx src/RDHManip.cxx src/OrbitInfo.cxx
13-
PUBLIC_LINK_LIBRARIES O2::MCHRawCommon O2::MCHRawElecMap O2::DetectorsRaw
12+
SOURCES src/PageDecoder.cxx src/DataDecoder.cxx src/RDHManip.cxx src/OrbitInfo.cxx
13+
PUBLIC_LINK_LIBRARIES O2::MCHRawCommon O2::MCHBase O2::MCHMappingInterface O2::MCHMappingImpl4 O2::MCHRawElecMap
14+
O2::DetectorsRaw
1415
PRIVATE_LINK_LIBRARIES O2::MCHRawImplHelpers)
1516

1617
if(BUILD_TESTING)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
///
12+
/// \file DataDecoder.h
13+
/// \author Andrea Ferrero
14+
///
15+
/// \brief Definition of the decoder for the MCH data
16+
///
17+
18+
#include <gsl/span>
19+
#include <unordered_set>
20+
21+
#include "Headers/RDHAny.h"
22+
#include "MCHBase/Digit.h"
23+
#include "MCHRawDecoder/OrbitInfo.h"
24+
#include "MCHRawDecoder/PageDecoder.h"
25+
26+
namespace o2
27+
{
28+
namespace mch
29+
{
30+
namespace raw
31+
{
32+
33+
using RdhHandler = std::function<void(o2::header::RDHAny*)>;
34+
35+
// custom hash for OrbitInfo objects
36+
struct OrbitInfoHash {
37+
std::size_t operator()(const OrbitInfo& info) const noexcept
38+
{
39+
return std::hash<uint64_t>{}(info.get());
40+
}
41+
};
42+
43+
//_________________________________________________________________
44+
//
45+
// Data decoder
46+
//_________________________________________________________________
47+
class DataDecoder
48+
{
49+
public:
50+
DataDecoder(SampaChannelHandler channelHandler, RdhHandler rdhHandler, std::string mapCRUfile, std::string mapFECfile, bool ds2manu, bool verbose);
51+
52+
void reset();
53+
void decodeBuffer(gsl::span<const std::byte> page);
54+
55+
const std::vector<o2::mch::Digit>& getOutputDigits() const { return mOutputDigits; }
56+
const std::unordered_set<OrbitInfo, OrbitInfoHash>& getOrbits() const { return mOrbits; }
57+
58+
private:
59+
void initElec2DetMapper(std::string filename);
60+
void initFee2SolarMapper(std::string filename);
61+
void init();
62+
63+
Elec2DetMapper mElec2Det{nullptr};
64+
FeeLink2SolarMapper mFee2Solar{nullptr};
65+
o2::mch::raw::PageDecoder mDecoder;
66+
size_t mNrdhs{0};
67+
std::vector<o2::mch::Digit> mOutputDigits;
68+
std::unordered_set<OrbitInfo, OrbitInfoHash> mOrbits; ///< list of orbits in the processed buffer
69+
70+
SampaChannelHandler mChannelHandler;
71+
std::function<void(o2::header::RDHAny*)> mRdhHandler;
72+
73+
std::string mMapCRUfile;
74+
std::string mMapFECfile;
75+
76+
bool mDebug{false};
77+
bool mDs2manu{false};
78+
};
79+
80+
} // namespace raw
81+
} // namespace mch
82+
} // end namespace o2

Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/SampaChannelHandler.h renamed to Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/DecodedDataHandlers.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// granted to it by virtue of its status as an Intergovernmental Organization
99
// or submit itself to any jurisdiction.
1010

11-
#ifndef O2_MCH_RAW_SAMPA_CHANNEL_HANDLER_H
12-
#define O2_MCH_RAW_SAMPA_CHANNEL_HANDLER_H
11+
#ifndef O2_MCH_DECODED_DATA_HANDLES_H
12+
#define O2_MCH_DECODED_DATA_HANDLES_H
1313

1414
#include <functional>
1515

@@ -27,6 +27,18 @@ namespace raw
2727
using SampaChannelHandler = std::function<void(DsElecId dsId,
2828
uint8_t channel,
2929
SampaCluster)>;
30+
31+
/// A SampaChannSampaHeartBeatHandler is a function that takes a chip index and
32+
/// a bunch crossing counter value found in a HeartBeat packet
33+
using SampaErrorHandler = std::function<void(DsElecId dsId,
34+
int8_t chip,
35+
uint32_t error)>;
36+
37+
struct DecodedDataHandlers {
38+
SampaChannelHandler sampaChannelHandler;
39+
SampaErrorHandler sampaErrorHandler;
40+
};
41+
3042
} // namespace raw
3143
} // namespace mch
3244
} // namespace o2
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#ifndef O2_MCH_RAW_ERROR_CODES_H
12+
#define O2_MCH_RAW_ERROR_CODES_H
13+
14+
namespace o2
15+
{
16+
namespace mch
17+
{
18+
namespace raw
19+
{
20+
21+
enum ErrorCodes {
22+
ErrorParity = 1, // 1
23+
ErrorHammingCorrectable = 1 << 1, // 2
24+
ErrorHammingUncorrectable = 1 << 2, // 4
25+
ErrorBadClusterSize = 1 << 3, // 8
26+
ErrorBadPacketType = 1 << 4, // 16
27+
ErrorBadHeartBeatPacket = 1 << 5, // 32
28+
ErrorBadIncompleteWord = 1 << 6, // 64
29+
ErrorTruncatedData = 1 << 7, // 128
30+
ErrorBadELinkID = 1 << 8, // 256
31+
ErrorBadLinkID = 1 << 9, // 512
32+
ErrorUnknownLinkID = 1 << 10 // 1024
33+
};
34+
35+
} // namespace raw
36+
} // namespace mch
37+
} // namespace o2
38+
39+
#endif

Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/PageDecoder.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <functional>
1515
#include <gsl/span>
1616
#include <map>
17-
#include "MCHRawDecoder/SampaChannelHandler.h"
17+
#include "MCHRawDecoder/DecodedDataHandlers.h"
1818
#include "MCHRawElecMap/Mapper.h"
1919

2020
namespace o2::mch::raw
@@ -32,11 +32,11 @@ using RawBuffer = gsl::span<const std::byte>;
3232
//
3333
// @param rdhBuffer a raw memory buffer containing (at least) one RDH
3434
// which information is used to decide which PageDecoder implementation to choose
35-
// @param channelHandler (optional) a callable object that will be called for each
36-
// decoded SampaCluster
35+
// @param decodedDataHandlers a structure with various callable objects (optional) that
36+
/// will be called for each decoded Sampa packet and in case of decoding errors
3737
//
3838
PageDecoder createPageDecoder(RawBuffer rdhBuffer,
39-
SampaChannelHandler channelHandler);
39+
DecodedDataHandlers decodedDataHandlers);
4040

4141
// Same as above but only to be used for special cases, e.g. when
4242
// trying to decode test beam data with an electronic mapping that
@@ -46,9 +46,17 @@ PageDecoder createPageDecoder(RawBuffer rdhBuffer,
4646
// object into a solarId.
4747
//
4848
PageDecoder createPageDecoder(RawBuffer rdhBuffer,
49-
SampaChannelHandler channelHandler,
49+
DecodedDataHandlers decodedDataHandlers,
5050
FeeLink2SolarMapper fee2solar);
5151

52+
// Alternative versions of the same functions, taking a SampaChannelHandler as parameter.
53+
[[deprecated("Use createPageDecoder(RawBuffer,DecodedDataHandlers) instead.")]] PageDecoder createPageDecoder(RawBuffer rdhBuffer,
54+
SampaChannelHandler channelHandler);
55+
56+
[[deprecated("Use createPageDecoder(RawBuffer,DecodedDataHandlers,fee2solar) instead.")]] PageDecoder createPageDecoder(RawBuffer rdhBuffer,
57+
SampaChannelHandler channelHandler,
58+
FeeLink2SolarMapper fee2solar);
59+
5260
// A PageParser loops over the given buffer and apply the given page decoder
5361
// to each page.
5462
using PageParser = std::function<void(RawBuffer buffer, PageDecoder pageDecoder)>;

Detectors/MUON/MCH/Raw/Decoder/src/BareElinkDecoder.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "Assertions.h"
1515
#include "MCHRawCommon/DataFormats.h"
1616
#include "MCHRawCommon/SampaHeader.h"
17-
#include "MCHRawDecoder/SampaChannelHandler.h"
17+
#include "MCHRawDecoder/DecodedDataHandlers.h"
1818
#include <bitset>
1919
#include <fmt/format.h>
2020
#include <fmt/printf.h>
@@ -33,7 +33,7 @@ namespace o2::mch::raw
3333
///
3434
/// Bits coming from parts of the GBT words are added to the Elink using the
3535
/// append() method and each time a SampaCluster is decoded,
36-
/// it is passed to the SampaChannelHandler for further processing (or none).
36+
/// it is passed to the DecodedDataHandlers for further processing (or none).
3737
///
3838
/// \nosubgrouping
3939
///
@@ -44,9 +44,9 @@ class BareElinkDecoder
4444
/// Constructor.
4545
/// \param dsId the (electronic) id of the dual sampa this elink
4646
/// is connected to
47-
/// \param sampaChannelHandler a callable that is passed
48-
/// each SampaCluster that will be decoded
49-
BareElinkDecoder(DsElecId dsId, SampaChannelHandler sampaChannelHandler);
47+
/// \param decodedDataHandlers a structure with various callable that
48+
/// handle the Sampa packets and decoding errors
49+
BareElinkDecoder(DsElecId dsId, DecodedDataHandlers decodedDataHandlers);
5050

5151
/** @name Main interface
5252
*/
@@ -104,7 +104,7 @@ class BareElinkDecoder
104104

105105
private:
106106
DsElecId mDsId;
107-
SampaChannelHandler mSampaChannelHandler; //< The callable that will deal with the SampaCluster objects we decode
107+
DecodedDataHandlers mDecodedDataHandlers; //< The structure with the callables that deal with the Sampa packets and the decoding errors
108108
SampaHeader mSampaHeader; //< Current SampaHeader
109109
uint64_t mBitBuffer; //< Our internal bit stream buffer
110110
/** @name internal global counters
@@ -154,9 +154,9 @@ std::string bitBufferString(const std::bitset<50>& bs, int imax)
154154

155155
template <typename CHARGESUM>
156156
BareElinkDecoder<CHARGESUM>::BareElinkDecoder(DsElecId dsId,
157-
SampaChannelHandler sampaChannelHandler)
157+
DecodedDataHandlers decodedDataHandlers)
158158
: mDsId{dsId},
159-
mSampaChannelHandler{sampaChannelHandler},
159+
mDecodedDataHandlers{decodedDataHandlers},
160160
mSampaHeader{},
161161
mBitBuffer{},
162162
mNofSync{},
@@ -422,20 +422,20 @@ std::ostream& operator<<(std::ostream& os, const o2::mch::raw::BareElinkDecoder<
422422
template <>
423423
void BareElinkDecoder<ChargeSumMode>::sendCluster()
424424
{
425-
if (mSampaChannelHandler) {
426-
mSampaChannelHandler(mDsId,
427-
channelNumber64(mSampaHeader),
428-
SampaCluster(mTimestamp, mSampaHeader.bunchCrossingCounter(), mClusterSum, mClusterSize));
425+
SampaChannelHandler handler = mDecodedDataHandlers.sampaChannelHandler;
426+
if (handler) {
427+
handler(mDsId, channelNumber64(mSampaHeader),
428+
SampaCluster(mTimestamp, mSampaHeader.bunchCrossingCounter(), mClusterSum, mClusterSize));
429429
}
430430
}
431431

432432
template <>
433433
void BareElinkDecoder<SampleMode>::sendCluster()
434434
{
435-
if (mSampaChannelHandler) {
436-
mSampaChannelHandler(mDsId,
437-
channelNumber64(mSampaHeader),
438-
SampaCluster(mTimestamp, mSampaHeader.bunchCrossingCounter(), mSamples));
435+
SampaChannelHandler handler = mDecodedDataHandlers.sampaChannelHandler;
436+
if (handler) {
437+
handler(mDsId, channelNumber64(mSampaHeader),
438+
SampaCluster(mTimestamp, mSampaHeader.bunchCrossingCounter(), mSamples));
439439
}
440440
mSamples.clear();
441441
}

Detectors/MUON/MCH/Raw/Decoder/src/BareGBTDecoder.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#include <array>
1515
#include "BareElinkDecoder.h"
16-
#include "MCHRawDecoder/SampaChannelHandler.h"
16+
#include "MCHRawDecoder/DecodedDataHandlers.h"
1717
#include <gsl/span>
1818
#include <fmt/printf.h>
1919
#include <fmt/format.h>
@@ -40,8 +40,9 @@ class BareGBTDecoder : public PayloadDecoder<BareGBTDecoder<CHARGESUM>>
4040
public:
4141
/// Constructor.
4242
/// \param solarId
43-
/// \param sampaChannelHandler the callable that will handle each SampaCluster
44-
BareGBTDecoder(uint16_t solarId, SampaChannelHandler sampaChannelHandler);
43+
/// \param decodedDataHandlers a structure with various callable that
44+
/// handle the Sampa packets and decoding errors
45+
BareGBTDecoder(uint16_t solarId, DecodedDataHandlers decodedDataHandlers);
4546

4647
/** @name Main interface
4748
*/
@@ -81,10 +82,10 @@ using namespace boost::multiprecision;
8182

8283
template <typename CHARGESUM>
8384
BareGBTDecoder<CHARGESUM>::BareGBTDecoder(uint16_t solarId,
84-
SampaChannelHandler sampaChannelHandler)
85-
: PayloadDecoder<BareGBTDecoder<CHARGESUM>>(sampaChannelHandler),
85+
DecodedDataHandlers decodedDataHandlers)
86+
: PayloadDecoder<BareGBTDecoder<CHARGESUM>>(decodedDataHandlers),
8687
mSolarId{solarId},
87-
mElinks{impl::makeArray<40>([=](uint8_t i) { return BareElinkDecoder<CHARGESUM>(DsElecId{solarId, static_cast<uint8_t>(i / 5), static_cast<uint8_t>(i % 5)}, sampaChannelHandler); })},
88+
mElinks{impl::makeArray<40>([=](uint8_t i) { return BareElinkDecoder<CHARGESUM>(DsElecId{solarId, static_cast<uint8_t>(i / 5), static_cast<uint8_t>(i % 5)}, decodedDataHandlers); })},
8889
mNofGbtWordsSeens{0}
8990
{
9091
}

0 commit comments

Comments
 (0)