Skip to content

Commit 2d95389

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

File tree

3 files changed

+77
-54
lines changed

3 files changed

+77
-54
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: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,28 @@ namespace o2
2929
namespace itsmft
3030
{
3131

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)
32+
template <int N>
33+
EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool getDigits)
34+
: mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, N), mGetDigits(getDigits)
3435
{
3536
assert(orig == o2::header::gDataOriginITS || orig == o2::header::gDataOriginMFT);
36-
mDetPrefix = orig == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
37+
mDetPrefix = Origin == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
3738
mTimer.Stop();
3839
mTimer.Reset();
3940
mCTFCoder.setVerbosity(verbosity);
4041
mCTFCoder.setDictBinding(std::string("ctfdict") + mDetPrefix);
4142
}
4243

43-
void EntropyDecoderSpec::init(o2::framework::InitContext& ic)
44+
template <int N>
45+
void EntropyDecoderSpec<N>::init(o2::framework::InitContext& ic)
4446
{
4547
mCTFCoder.init<CTF>(ic);
4648
mMaskNoise = ic.options().get<bool>("mask-noise");
4749
mUseClusterDictionary = !ic.options().get<bool>("ignore-cluster-dictionary");
4850
}
4951

50-
void EntropyDecoderSpec::run(ProcessingContext& pc)
52+
template <int N>
53+
void EntropyDecoderSpec<N>::run(ProcessingContext& pc)
5154
{
5255
if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) {
5356
mTimer.Reset();
@@ -81,15 +84,28 @@ void EntropyDecoderSpec::run(ProcessingContext& pc)
8184
LOG(info) << "Decoded " << compcl.size() << " clusters in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
8285
}
8386
pc.outputs().snapshot({"ctfrep", 0}, iosize);
87+
88+
// hack: output empty messages
89+
for (uint32_t iLayer{1}; iLayer < NLayers; ++iLayer) {
90+
pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{"ROframes", iLayer});
91+
if (mGetDigits) {
92+
pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{"Digits", iLayer});
93+
} else {
94+
pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{"compClusters", iLayer});
95+
pc.outputs().make<std::vector<unsigned char>>(OutputRef{"patterns", iLayer});
96+
}
97+
}
8498
}
8599

86-
void EntropyDecoderSpec::endOfStream(EndOfStreamContext& ec)
100+
template <int N>
101+
void EntropyDecoderSpec<N>::endOfStream(EndOfStreamContext& ec)
87102
{
88103
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);
104+
Origin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
90105
}
91106

92-
void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
107+
template <int N>
108+
void EntropyDecoderSpec<N>::updateTimeDependentParams(ProcessingContext& pc)
93109
{
94110
if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
95111
if (mMaskNoise) {
@@ -102,15 +118,16 @@ void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
102118
mCTFCoder.updateTimeDependentParams(pc, true);
103119
}
104120

105-
void EntropyDecoderSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj)
121+
template <int N>
122+
void EntropyDecoderSpec<N>::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj)
106123
{
107-
if (matcher == ConcreteDataMatcher(mOrigin, "NOISEMAP", 0)) {
124+
if (matcher == ConcreteDataMatcher(Origin, "NOISEMAP", 0)) {
108125
mNoiseMap = (o2::itsmft::NoiseMap*)obj;
109-
LOG(info) << mOrigin.as<std::string>() << " noise map updated";
126+
LOG(info) << Origin.as<std::string>() << " noise map updated";
110127
return;
111128
}
112-
if (matcher == ConcreteDataMatcher(mOrigin, "CLUSDICT", 0)) {
113-
LOG(info) << mOrigin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
129+
if (matcher == ConcreteDataMatcher(Origin, "CLUSDICT", 0)) {
130+
LOG(info) << Origin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
114131
mPattIdConverter.setDictionary((const TopologyDictionary*)obj);
115132
return;
116133
}
@@ -119,42 +136,52 @@ void EntropyDecoderSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matche
119136
}
120137
}
121138

122-
DataProcessorSpec getEntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits, unsigned int sspec)
139+
template <int N>
140+
DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec)
123141
{
142+
using EntropyDecoder = EntropyDecoderSpec<N>;
143+
144+
std::string det = EntropyDecoder::Origin.template as<std::string>();
145+
std::string nm = "_" + det;
146+
std::vector<InputSpec> inputs;
147+
inputs.emplace_back(std::string("ctf") + nm, EntropyDecoder::Origin, "CTFDATA", sspec, Lifetime::Timeframe);
148+
inputs.emplace_back(std::string("noise") + nm, EntropyDecoder::Origin, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", det)));
149+
inputs.emplace_back(std::string("cldict") + nm, EntropyDecoder::Origin, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", det)));
150+
inputs.emplace_back(std::string("ctfdict") + nm, EntropyDecoder::Origin, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", det)));
151+
inputs.emplace_back(std::string("trigoffset"), "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
152+
124153
std::vector<OutputSpec> outputs;
125154
// this is a special dummy input which makes sense only in sync workflows
126155

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

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});
159+
for (uint32_t iLayer{0}; iLayer < EntropyDecoder::NLayers; ++iLayer) {
160+
if (getDigits) {
161+
outputs.emplace_back(OutputSpec{{"Digits"}, EntropyDecoder::Origin, "DIGITS", iLayer, Lifetime::Timeframe});
162+
outputs.emplace_back(OutputSpec{{"ROframes"}, EntropyDecoder::Origin, "DIGITSROF", iLayer, Lifetime::Timeframe});
163+
} else {
164+
outputs.emplace_back(OutputSpec{{"compClusters"}, EntropyDecoder::Origin, "COMPCLUSTERS", iLayer, Lifetime::Timeframe});
165+
outputs.emplace_back(OutputSpec{{"ROframes"}, EntropyDecoder::Origin, "CLUSTERSROF", iLayer, Lifetime::Timeframe});
166+
outputs.emplace_back(OutputSpec{{"patterns"}, EntropyDecoder::Origin, "PATTERNS", iLayer, Lifetime::Timeframe});
167+
}
137168
}
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"));
169+
outputs.emplace_back(OutputSpec{{"ctfrep"}, EntropyDecoder::Origin, "CTFDECREP", 0, Lifetime::Timeframe});
146170

147171
return DataProcessorSpec{
148-
EntropyDecoderSpec::getName(orig),
149-
inputs,
150-
outputs,
151-
AlgorithmSpec{adaptFromTask<EntropyDecoderSpec>(orig, verbosity, getDigits)},
152-
Options{
172+
.name = EntropyDecoder::DeviceName,
173+
.inputs = inputs,
174+
.outputs = outputs,
175+
.algorithm = AlgorithmSpec{adaptFromTask<EntropyDecoder>(verbosity, getDigits)},
176+
.options = Options{
153177
{"ctf-dict", VariantType::String, "ccdb", {"CTF dictionary: empty or ccdb=CCDB, none=no external dictionary otherwise: local filename"}},
154178
{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
155179
{"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"}}}};
180+
{"and-version", VariantType::String, {"version of and entropy coder implementation to use"}}}};
157181
}
158182

183+
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, getDigits, sspec); }
184+
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, getDigits, sspec); }
185+
159186
} // namespace itsmft
160187
} // namespace o2

0 commit comments

Comments
 (0)