Skip to content

Commit 936969b

Browse files
committed
ITSMFT: CTF decoder output per layer
Signed-off-by: Felix Schlepper <[email protected]>
1 parent aaa5099 commit 936969b

File tree

3 files changed

+152
-68
lines changed

3 files changed

+152
-68
lines changed

Detectors/CTF/workflow/src/ctf-reader-workflow.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
181181

182182
// add decoders for all allowed detectors.
183183
if (ctfInput.detMask[DetID::ITS]) {
184-
addSpecs(o2::itsmft::getEntropyDecoderSpec(DetID::getDataOrigin(DetID::ITS), verbosity, configcontext.options().get<bool>("its-digits"), ctfInput.subspec));
184+
addSpecs(o2::itsmft::getITSEntropyDecoderSpec(verbosity, configcontext.options().get<bool>("its-digits"), ctfInput.subspec));
185185
}
186186
if (ctfInput.detMask[DetID::MFT]) {
187-
addSpecs(o2::itsmft::getEntropyDecoderSpec(DetID::getDataOrigin(DetID::MFT), verbosity, configcontext.options().get<bool>("mft-digits"), ctfInput.subspec));
187+
addSpecs(o2::itsmft::getMFTEntropyDecoderSpec(verbosity, configcontext.options().get<bool>("mft-digits"), ctfInput.subspec));
188188
}
189189
if (ctfInput.detMask[DetID::TPC]) {
190190
addSpecs(o2::tpc::getEntropyDecoderSpec(verbosity, ctfInput.subspec));

Detectors/ITSMFT/common/workflow/include/ITSMFTWorkflow/EntropyDecoderSpec.h

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,49 +20,45 @@
2020
#include "Headers/DataHeader.h"
2121
#include "ITSMFTReconstruction/CTFCoder.h"
2222
#include "DataFormatsITSMFT/NoiseMap.h"
23+
#include "ITSMFTBase/DPLAlpideParam.h"
2324
#include "ITSMFTReconstruction/LookUp.h"
2425
#include <TStopwatch.h>
25-
#include <memory>
2626

27-
namespace o2
28-
{
29-
namespace itsmft
27+
namespace o2::itsmft
3028
{
3129

30+
template <int N>
3231
class EntropyDecoderSpec : public o2::framework::Task
3332
{
3433
public:
35-
EntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits = false);
34+
static constexpr o2::header::DataOrigin Origin{N == o2::detectors::DetID::ITS ? o2::header::gDataOriginITS : o2::header::gDataOriginMFT};
35+
static constexpr int NLayers{o2::itsmft::DPLAlpideParam<N>::getNLayers()};
36+
static constexpr const char* DeviceName{N == o2::detectors::DetID::ITS ? "its-entropy-decoder" : "mft-entropy-decoder"};
37+
38+
EntropyDecoderSpec(int verbosity, bool getDigits = false);
3639
~EntropyDecoderSpec() override = default;
3740
void init(o2::framework::InitContext& ic) final;
3841
void run(o2::framework::ProcessingContext& pc) final;
3942
void endOfStream(o2::framework::EndOfStreamContext& ec) final;
4043
void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final;
4144

42-
static auto getName(o2::header::DataOrigin orig) { return std::string{orig == o2::header::gDataOriginITS ? ITSDeviceName : MFTDeviceName}; }
43-
4445
private:
4546
void updateTimeDependentParams(o2::framework::ProcessingContext& pc);
4647

47-
static constexpr std::string_view ITSDeviceName = "its-entropy-decoder";
48-
static constexpr std::string_view MFTDeviceName = "mft-entropy-decoder";
49-
o2::header::DataOrigin mOrigin = o2::header::gDataOriginInvalid;
5048
o2::itsmft::CTFCoder mCTFCoder;
5149
const NoiseMap* mNoiseMap = nullptr;
5250
LookUp mPattIdConverter;
5351
bool mGetDigits{false};
5452
bool mMaskNoise{false};
5553
bool mUseClusterDictionary{true};
56-
std::string mDetPrefix{};
57-
58-
std::string mCTFDictPath{};
54+
std::string mDetPrefix;
55+
std::string mCTFDictPath;
5956
TStopwatch mTimer;
6057
};
6158

62-
/// create a processor spec
63-
framework::DataProcessorSpec getEntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits, unsigned int sspec);
59+
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec);
60+
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec);
6461

65-
} // namespace itsmft
66-
} // namespace o2
62+
} // namespace o2::itsmft
6763

6864
#endif

Detectors/ITSMFT/common/workflow/src/EntropyDecoderSpec.cxx

Lines changed: 137 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "ITSMFTReconstruction/ClustererParam.h"
2222
#include "DetectorsCommonDataFormats/DetectorNameConf.h"
2323
#include "DataFormatsITSMFT/PhysTrigger.h"
24+
#include "ITSMFTReconstruction/ChipMappingITS.h"
25+
#include "ITSMFTReconstruction/ChipMappingMFT.h"
2426

2527
using namespace o2::framework;
2628

@@ -29,25 +31,28 @@ namespace o2
2931
namespace itsmft
3032
{
3133

32-
EntropyDecoderSpec::EntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits)
33-
: mOrigin(orig), mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, orig == o2::header::gDataOriginITS ? o2::detectors::DetID::ITS : o2::detectors::DetID::MFT), mGetDigits(getDigits)
34+
template <int N>
35+
EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool getDigits)
36+
: mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, N), mGetDigits(getDigits)
3437
{
3538
assert(orig == o2::header::gDataOriginITS || orig == o2::header::gDataOriginMFT);
36-
mDetPrefix = orig == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
39+
mDetPrefix = Origin == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
3740
mTimer.Stop();
3841
mTimer.Reset();
3942
mCTFCoder.setVerbosity(verbosity);
4043
mCTFCoder.setDictBinding(std::string("ctfdict") + mDetPrefix);
4144
}
4245

43-
void EntropyDecoderSpec::init(o2::framework::InitContext& ic)
46+
template <int N>
47+
void EntropyDecoderSpec<N>::init(o2::framework::InitContext& ic)
4448
{
4549
mCTFCoder.init<CTF>(ic);
4650
mMaskNoise = ic.options().get<bool>("mask-noise");
4751
mUseClusterDictionary = !ic.options().get<bool>("ignore-cluster-dictionary");
4852
}
4953

50-
void EntropyDecoderSpec::run(ProcessingContext& pc)
54+
template <int N>
55+
void EntropyDecoderSpec<N>::run(ProcessingContext& pc)
5156
{
5257
if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) {
5358
mTimer.Reset();
@@ -63,33 +68,105 @@ void EntropyDecoderSpec::run(ProcessingContext& pc)
6368
// this produces weird memory problems in unrelated devices, to be understood
6469
// auto& trigs = pc.outputs().make<std::vector<o2::itsmft::PhysTrigger>>(OutputRef{"phystrig"}); // dummy output
6570

66-
auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{"ROframes"});
67-
if (mGetDigits) {
68-
auto& digits = pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{"Digits"});
69-
if (buff.size()) {
70-
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, digits, mNoiseMap, mPattIdConverter);
71+
if constexpr (DPLAlpideParam<N>::supportsStaggering()) {
72+
// for now we need to 'mock' the staggered output and sort ordering ourselves
73+
std::vector<o2::itsmft::ROFRecord> rofs;
74+
std::vector<o2::itsmft::Digit> digits;
75+
std::vector<o2::itsmft::CompClusterExt> clusters;
76+
std::vector<unsigned char> patterns;
77+
// do the actual read
78+
if (mGetDigits) {
79+
if (buff.size()) {
80+
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, digits, mNoiseMap, mPattIdConverter);
81+
}
82+
mTimer.Stop();
83+
LOG(info) << "Decoded " << digits.size() << " digits in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
84+
} else {
85+
if (buff.size()) {
86+
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, clusters, patterns, mNoiseMap, mPattIdConverter);
87+
}
88+
mTimer.Stop();
89+
LOG(info) << "Decoded " << clusters.size() << " clusters in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
90+
}
91+
std::array<std::vector<o2::itsmft::ROFRecord>, NLayers> rofsPerLayer;
92+
std::array<std::vector<o2::itsmft::Digit>, NLayers> digitsPerLayer;
93+
std::array<std::vector<o2::itsmft::CompClusterExt>, NLayers> clustersPerLayer;
94+
std::array<std::vector<unsigned char>, NLayers> patternsPerLayer;
95+
std::array<std::vector<int>, NLayers> firstEntries;
96+
std::array<std::vector<int>, NLayers> nEntries;
97+
for (int iLayer{0}; iLayer < NLayers; ++iLayer) {
98+
rofsPerLayer[iLayer] = rofs;
99+
firstEntries[iLayer].resize(rofs.size(), 0);
100+
nEntries[iLayer].resize(rofs.size(), 0);
101+
}
102+
// now we need to filter the data per layer
103+
// TODO implement also for cluster input
104+
for (size_t iROF{0}; iROF < rofs.size(); ++iROF) {
105+
const auto& rof = rofs[iROF];
106+
for (int iEntry{rof.getFirstEntry()}; iEntry < (rof.getFirstEntry() + rof.getNEntries()); ++iEntry) {
107+
const auto& dig = digits[iEntry];
108+
int lay = ChipMappingITS::getLayer(dig.getChipIndex());
109+
digitsPerLayer[lay].push_back(dig);
110+
++(nEntries[lay][iROF]);
111+
}
112+
}
113+
for (int iLayer{0}; iLayer < NLayers; ++iLayer) {
114+
std::exclusive_scan(nEntries[iLayer].begin(), nEntries[iLayer].end(), firstEntries[iLayer].begin(), 0);
115+
for (int iROF{0}; iROF < rofs.size(); ++iROF) {
116+
rofsPerLayer[iLayer][iROF].setFirstEntry(firstEntries[iLayer][iROF]);
117+
rofsPerLayer[iLayer][iROF].setNEntries(nEntries[iLayer][iROF]);
118+
}
119+
}
120+
for (uint32_t iLayer{0}; iLayer < NLayers; ++iLayer) {
121+
pc.outputs().snapshot(OutputRef{"ROframes", iLayer}, rofsPerLayer[iLayer]);
122+
if (mGetDigits) {
123+
pc.outputs().snapshot(OutputRef{"Digits", iLayer}, digitsPerLayer[iLayer]);
124+
} else {
125+
pc.outputs().snapshot(OutputRef{"compClusters", iLayer}, clustersPerLayer[iLayer]);
126+
pc.outputs().snapshot(OutputRef{"patterns", iLayer}, patternsPerLayer[iLayer]);
127+
}
71128
}
72-
mTimer.Stop();
73-
LOG(info) << "Decoded " << digits.size() << " digits in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
74129
} else {
75-
auto& compcl = pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{"compClusters"});
76-
auto& patterns = pc.outputs().make<std::vector<unsigned char>>(OutputRef{"patterns"});
77-
if (buff.size()) {
78-
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, compcl, patterns, mNoiseMap, mPattIdConverter);
130+
auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{"ROframes", 0});
131+
if (mGetDigits) {
132+
auto& digits = pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{"Digits", 0});
133+
if (buff.size()) {
134+
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, digits, mNoiseMap, mPattIdConverter);
135+
}
136+
mTimer.Stop();
137+
LOG(info) << "Decoded " << digits.size() << " digits in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
138+
} else {
139+
auto& compcl = pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{"compClusters", 0});
140+
auto& patterns = pc.outputs().make<std::vector<unsigned char>>(OutputRef{"patterns", 0});
141+
if (buff.size()) {
142+
iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, compcl, patterns, mNoiseMap, mPattIdConverter);
143+
}
144+
mTimer.Stop();
145+
LOG(info) << "Decoded " << compcl.size() << " clusters in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
146+
}
147+
// hack: output empty messages to avoid dropping the TF
148+
for (uint32_t iLayer{1}; iLayer < NLayers; ++iLayer) {
149+
pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{"ROframes", iLayer});
150+
if (mGetDigits) {
151+
pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{"Digits", iLayer});
152+
} else {
153+
pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{"compClusters", iLayer});
154+
pc.outputs().make<std::vector<unsigned char>>(OutputRef{"patterns", iLayer});
155+
}
79156
}
80-
mTimer.Stop();
81-
LOG(info) << "Decoded " << compcl.size() << " clusters in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
82157
}
83158
pc.outputs().snapshot({"ctfrep", 0}, iosize);
84-
}
159+
} // namespace itsmft
85160

86-
void EntropyDecoderSpec::endOfStream(EndOfStreamContext& ec)
161+
template <int N>
162+
void EntropyDecoderSpec<N>::endOfStream(EndOfStreamContext& ec)
87163
{
88164
LOGF(info, "%s Entropy Decoding total timing: Cpu: %.3e Real: %.3e s in %d slots",
89-
mOrigin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
165+
Origin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
90166
}
91167

92-
void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
168+
template <int N>
169+
void EntropyDecoderSpec<N>::updateTimeDependentParams(ProcessingContext& pc)
93170
{
94171
if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
95172
if (mMaskNoise) {
@@ -102,15 +179,16 @@ void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
102179
mCTFCoder.updateTimeDependentParams(pc, true);
103180
}
104181

105-
void EntropyDecoderSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj)
182+
template <int N>
183+
void EntropyDecoderSpec<N>::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj)
106184
{
107-
if (matcher == ConcreteDataMatcher(mOrigin, "NOISEMAP", 0)) {
185+
if (matcher == ConcreteDataMatcher(Origin, "NOISEMAP", 0)) {
108186
mNoiseMap = (o2::itsmft::NoiseMap*)obj;
109-
LOG(info) << mOrigin.as<std::string>() << " noise map updated";
187+
LOG(info) << Origin.as<std::string>() << " noise map updated";
110188
return;
111189
}
112-
if (matcher == ConcreteDataMatcher(mOrigin, "CLUSDICT", 0)) {
113-
LOG(info) << mOrigin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
190+
if (matcher == ConcreteDataMatcher(Origin, "CLUSDICT", 0)) {
191+
LOG(info) << Origin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
114192
mPattIdConverter.setDictionary((const TopologyDictionary*)obj);
115193
return;
116194
}
@@ -119,42 +197,52 @@ void EntropyDecoderSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matche
119197
}
120198
}
121199

122-
DataProcessorSpec getEntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits, unsigned int sspec)
200+
template <int N>
201+
DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec)
123202
{
203+
using EntropyDecoder = EntropyDecoderSpec<N>;
204+
205+
std::string det = EntropyDecoder::Origin.template as<std::string>();
206+
std::string nm = "_" + det;
207+
std::vector<InputSpec> inputs;
208+
inputs.emplace_back(std::string("ctf") + nm, EntropyDecoder::Origin, "CTFDATA", sspec, Lifetime::Timeframe);
209+
inputs.emplace_back(std::string("noise") + nm, EntropyDecoder::Origin, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", det)));
210+
inputs.emplace_back(std::string("cldict") + nm, EntropyDecoder::Origin, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", det)));
211+
inputs.emplace_back(std::string("ctfdict") + nm, EntropyDecoder::Origin, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", det)));
212+
inputs.emplace_back(std::string("trigoffset"), "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
213+
124214
std::vector<OutputSpec> outputs;
125215
// this is a special dummy input which makes sense only in sync workflows
126216

127217
// this produces weird memory problems in unrelated devices, to be understood
128218
// outputs.emplace_back(OutputSpec{{"phystrig"}, orig, "PHYSTRIG", 0, Lifetime::Timeframe});
129219

130-
if (getDigits) {
131-
outputs.emplace_back(OutputSpec{{"Digits"}, orig, "DIGITS", 0, Lifetime::Timeframe});
132-
outputs.emplace_back(OutputSpec{{"ROframes"}, orig, "DIGITSROF", 0, Lifetime::Timeframe});
133-
} else {
134-
outputs.emplace_back(OutputSpec{{"compClusters"}, orig, "COMPCLUSTERS", 0, Lifetime::Timeframe});
135-
outputs.emplace_back(OutputSpec{{"ROframes"}, orig, "CLUSTERSROF", 0, Lifetime::Timeframe});
136-
outputs.emplace_back(OutputSpec{{"patterns"}, orig, "PATTERNS", 0, Lifetime::Timeframe});
220+
for (uint32_t iLayer{0}; iLayer < EntropyDecoder::NLayers; ++iLayer) {
221+
if (getDigits) {
222+
outputs.emplace_back(OutputSpec{{"Digits"}, EntropyDecoder::Origin, "DIGITS", iLayer, Lifetime::Timeframe});
223+
outputs.emplace_back(OutputSpec{{"ROframes"}, EntropyDecoder::Origin, "DIGITSROF", iLayer, Lifetime::Timeframe});
224+
} else {
225+
outputs.emplace_back(OutputSpec{{"compClusters"}, EntropyDecoder::Origin, "COMPCLUSTERS", iLayer, Lifetime::Timeframe});
226+
outputs.emplace_back(OutputSpec{{"ROframes"}, EntropyDecoder::Origin, "CLUSTERSROF", iLayer, Lifetime::Timeframe});
227+
outputs.emplace_back(OutputSpec{{"patterns"}, EntropyDecoder::Origin, "PATTERNS", iLayer, Lifetime::Timeframe});
228+
}
137229
}
138-
outputs.emplace_back(OutputSpec{{"ctfrep"}, orig, "CTFDECREP", 0, Lifetime::Timeframe});
139-
std::string nm = orig == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
140-
std::vector<InputSpec> inputs;
141-
inputs.emplace_back(std::string("ctf") + nm, orig, "CTFDATA", sspec, Lifetime::Timeframe);
142-
inputs.emplace_back(std::string("noise") + nm, orig, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", orig.as<std::string>())));
143-
inputs.emplace_back(std::string("cldict") + nm, orig, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", orig.as<std::string>())));
144-
inputs.emplace_back(std::string("ctfdict") + nm, orig, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", orig.as<std::string>())));
145-
inputs.emplace_back(std::string("trigoffset"), "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
230+
outputs.emplace_back(OutputSpec{{"ctfrep"}, EntropyDecoder::Origin, "CTFDECREP", 0, Lifetime::Timeframe});
146231

147232
return DataProcessorSpec{
148-
EntropyDecoderSpec::getName(orig),
149-
inputs,
150-
outputs,
151-
AlgorithmSpec{adaptFromTask<EntropyDecoderSpec>(orig, verbosity, getDigits)},
152-
Options{
233+
.name = EntropyDecoder::DeviceName,
234+
.inputs = inputs,
235+
.outputs = outputs,
236+
.algorithm = AlgorithmSpec{adaptFromTask<EntropyDecoder>(verbosity, getDigits)},
237+
.options = Options{
153238
{"ctf-dict", VariantType::String, "ccdb", {"CTF dictionary: empty or ccdb=CCDB, none=no external dictionary otherwise: local filename"}},
154239
{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
155240
{"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}},
156-
{"ans-version", VariantType::String, {"version of ans entropy coder implementation to use"}}}};
241+
{"and-version", VariantType::String, {"version of and entropy coder implementation to use"}}}};
157242
}
158243

244+
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, getDigits, sspec); }
245+
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, getDigits, sspec); }
246+
159247
} // namespace itsmft
160248
} // namespace o2

0 commit comments

Comments
 (0)