Project
Loading...
Searching...
No Matches
EntropyDecoderSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
14#include <vector>
15
25
26using namespace o2::framework;
27
28namespace o2
29{
30namespace itsmft
31{
32
33template <int N>
34std::string EntropyDecoderSpec<N>::getBinding(const std::string& name, int spec)
35{
36 return fmt::format("{}_{}", name, spec);
37}
38
39template <int N>
40EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, const std::string& ctfdictOpt)
41 : mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, doStag, ctfdictOpt), mDoStaggering(doStag), mGetDigits(getDigits)
42{
43 mTimer.Stop();
44 mTimer.Reset();
45 mCTFCoder.setVerbosity(verbosity);
46 mCTFCoder.setDictBinding(std::string("ctfdict_") + ID.getName());
47}
48
49template <int N>
51{
52 mCTFCoder.template init<CTF>(ic);
53 mMaskNoise = ic.options().get<bool>("mask-noise");
54 mUseClusterDictionary = !ic.options().get<bool>("ignore-cluster-dictionary");
55}
56
57template <int N>
59{
61 mTimer.Reset();
62 }
63 auto cput = mTimer.CpuTime();
64 mTimer.Start(false);
65 o2::ctf::CTFIOSize iosize;
66 size_t ndigcl = 0, nrofs = 0;
67 updateTimeDependentParams(pc);
68 std::string nm = ID.getName();
69 uint32_t nLayers = mDoStaggering ? DPLAlpideParam<N>::getNLayers() : 1;
70 for (uint32_t iLayer = 0; iLayer < nLayers; iLayer++) {
71 auto buff = pc.inputs().get<gsl::span<o2::ctf::BufferType>>(getBinding(nm + "CTF", iLayer));
72 // since the buff is const, we cannot use EncodedBlocks::relocate directly, instead we wrap its data to another flat object
73 // const auto ctfImage = o2::itsmft::CTF::getImage(buff.data());
74 const auto& ctf = o2::itsmft::CTF::getImage(buff.data());
75 if (ctf.getHeader().maxStreams != nLayers) {
76 LOGP(fatal, "Number of streams {} in the CTF header is not equal to NLayers {} from AlpideParam in {}staggered mode",
77 ctf.getHeader().maxStreams, nLayers, mDoStaggering ? "" : "non-");
78 }
79 // this produces weird memory problems in unrelated devices, to be understood
80 // auto& trigs = pc.outputs().make<std::vector<o2::itsmft::PhysTrigger>>(OutputRef{"phystrig"}); // dummy output
81 auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{nm + "ROframes", iLayer});
82 if (mGetDigits) {
83 auto& digits = pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{nm + "Digits", iLayer});
84 if (buff.size()) {
85 iosize += mCTFCoder.decode(ctf, rofs, digits, mNoiseMap, mPattIdConverter);
86 }
87 ndigcl += digits.size();
88 nrofs += rofs.size();
89 } else {
90 auto& compcl = pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{nm + "compClusters", iLayer});
91 auto& patterns = pc.outputs().make<std::vector<unsigned char>>(OutputRef{nm + "patterns", iLayer});
92 if (buff.size()) {
93 iosize += mCTFCoder.decode(ctf, rofs, compcl, patterns, mNoiseMap, mPattIdConverter);
94 }
95 ndigcl += compcl.size();
96 }
97 }
98 pc.outputs().snapshot({nm + "ctfrep", 0}, iosize);
99 mTimer.Stop();
100 LOGP(info, "Decoded {} {} in {} ROFs of {} streams ({}) in {}staggerd mode in {} s", ndigcl, mGetDigits ? "digits" : "clusters",
101 nrofs, nLayers, iosize.asString(), mDoStaggering ? "" : "non-", mTimer.CpuTime() - cput);
102}
103
104template <int N>
106{
107 LOGP(info, "{} Entropy Decoding total timing: Cpu: {:.3e} Real: {:.3e} s in {} slots",
108 Origin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
109}
110
111template <int N>
113{
114 std::string nm = ID.getName();
115 if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
116 if (mMaskNoise) {
117 pc.inputs().get<o2::itsmft::NoiseMap*>(nm + "noise");
118 }
119 if (mGetDigits || mMaskNoise) {
120 pc.inputs().get<o2::itsmft::TopologyDictionary*>(nm + "cldict");
121 }
122 }
123 pc.inputs().get<o2::itsmft::DPLAlpideParam<N>*>(nm + "alppar");
124 mCTFCoder.updateTimeDependentParams(pc, true);
125}
126
127template <int N>
129{
130 if (matcher == ConcreteDataMatcher(Origin, "NOISEMAP", 0)) {
131 mNoiseMap = (o2::itsmft::NoiseMap*)obj;
132 LOG(info) << Origin.as<std::string>() << " noise map updated";
133 return;
134 }
135 if (matcher == ConcreteDataMatcher(Origin, "CLUSDICT", 0)) {
136 LOG(info) << Origin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
137 mPattIdConverter.setDictionary((const TopologyDictionary*)obj);
138 return;
139 }
140 if (matcher == ConcreteDataMatcher(Origin, "ALPIDEPARAM", 0)) {
141 LOG(info) << "Alpide param updated";
142 return;
143 }
144 if (mCTFCoder.template finaliseCCDB<CTF>(matcher, obj)) {
145 return;
146 }
147}
148
149template <int N>
150DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
151{
154 uint32_t nLayers = doStag ? DPLAlpideParam<N>::getNLayers() : 1;
155
156 std::vector<InputSpec> inputs;
157 std::vector<OutputSpec> outputs;
158
159 // this produces weird memory problems in unrelated devices, to be understood
160 // outputs.emplace_back(OutputSpec{{"phystrig"}, Origin, "PHYSTRIG", 0, Lifetime::Timeframe});
161 std::string nm = ID.getName();
162 for (uint32_t iLayer = 0; iLayer < nLayers; ++iLayer) {
163 if (getDigits) {
164 outputs.emplace_back(OutputSpec{{nm + "Digits"}, Origin, "DIGITS", iLayer, Lifetime::Timeframe});
165 outputs.emplace_back(OutputSpec{{nm + "ROframes"}, Origin, "DIGITSROF", iLayer, Lifetime::Timeframe});
166 } else {
167 outputs.emplace_back(OutputSpec{{nm + "compClusters"}, Origin, "COMPCLUSTERS", iLayer, Lifetime::Timeframe});
168 outputs.emplace_back(OutputSpec{{nm + "ROframes"}, Origin, "CLUSTERSROF", iLayer, Lifetime::Timeframe});
169 outputs.emplace_back(OutputSpec{{nm + "patterns"}, Origin, "PATTERNS", iLayer, Lifetime::Timeframe});
170 }
171 inputs.emplace_back(EntropyDecoderSpec<N>::getBinding(nm + "CTF", iLayer), Origin, "CTFDATA", sspec * 100 + iLayer, Lifetime::Timeframe);
172 }
173 outputs.emplace_back(OutputSpec{{nm + "ctfrep"}, Origin, "CTFDECREP", 0, Lifetime::Timeframe});
174
175 inputs.emplace_back(nm + "alppar", Origin, "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Config/AlpideParam", Origin.as<std::string>())));
176 inputs.emplace_back(nm + "noise", Origin, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", Origin.as<std::string>())));
177 inputs.emplace_back(nm + "cldict", Origin, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", Origin.as<std::string>())));
178 if (ctfdictOpt.empty() || ctfdictOpt == "ccdb") {
179 inputs.emplace_back(std::string{"ctfdict_"} + ID.getName(), Origin, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", Origin.as<std::string>())));
180 }
181 inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
182
183 return DataProcessorSpec{
184 Origin == o2::header::gDataOriginITS ? "its-entropy-decoder" : "mft-entropy-decoder",
185 inputs,
186 outputs,
187 AlgorithmSpec{adaptFromTask<EntropyDecoderSpec<N>>(verbosity, doStag, getDigits, ctfdictOpt)},
188 Options{{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
189 {"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}},
190 {"ans-version", VariantType::String, {"version of ans entropy coder implementation to use"}}}};
191}
192
193framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
194{
195 return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
196}
197
198framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
199{
200 return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
201}
202
203} // namespace itsmft
204} // namespace o2
#define verbosity
Definition of the ITS/MFT clusterer settings.
Definition of the ITSMFT compact cluster.
Definition of the Names Generator class.
Convert CTF (EncodedBlocks) to clusters streams.
Definition Physics trigger record extracted from the ITS/MFT stream.
static auto getImage(const void *newHead)
get const image of the container wrapper, with pointers in the image relocated to new head
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr const char * getName(ID id)
names of defined detectors
Definition DetID.h:146
static constexpr ID ITS
Definition DetID.h:63
static constexpr ID MFT
Definition DetID.h:71
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
static constexpr o2::detectors::DetID ID
static std::string getBinding(const std::string &name, int spec)
void init(o2::framework::InitContext &ic) final
void run(o2::framework::ProcessingContext &pc) final
EntropyDecoderSpec(int verbosity, bool doStag, bool getDigits=false, const std::string &ctfdictOpt="none")
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
NoiseMap class for the ITS and MFT.
Definition NoiseMap.h:39
GLuint const GLchar * name
Definition glcorearb.h:781
constexpr o2::header::DataOrigin gDataOriginMFT
Definition DataHeader.h:572
constexpr o2::header::DataOrigin gDataOriginITS
Definition DataHeader.h:570
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string &ctfdictOpt)
DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string &ctfdictOpt)
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string &ctfdictOpt)
create a processor spec
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string asString() const
Definition CTFIOSize.cxx:19
static constexpr int getNLayers()
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits