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 if (buff.size()) {
75 const auto& ctf = o2::itsmft::CTF::getImage(buff.data());
76 if (ctf.getHeader().maxStreams != nLayers) {
77 LOGP(fatal, "Number of streams {} in the CTF header is not equal to NLayers {} from AlpideParam in {}staggered mode",
78 ctf.getHeader().maxStreams, nLayers, mDoStaggering ? "" : "non-");
79 }
80 }
81 // this produces weird memory problems in unrelated devices, to be understood
82 // auto& trigs = pc.outputs().make<std::vector<o2::itsmft::PhysTrigger>>(OutputRef{"phystrig"}); // dummy output
83 auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{nm + "ROframes", iLayer});
84 if (mGetDigits) {
85 auto& digits = pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{nm + "Digits", iLayer});
86 if (buff.size()) {
87 iosize += mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, digits, mNoiseMap, mPattIdConverter);
88 }
89 ndigcl += digits.size();
90 nrofs += rofs.size();
91 } else {
92 auto& compcl = pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{nm + "compClusters", iLayer});
93 auto& patterns = pc.outputs().make<std::vector<unsigned char>>(OutputRef{nm + "patterns", iLayer});
94 if (buff.size()) {
95 iosize += mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, compcl, patterns, mNoiseMap, mPattIdConverter);
96 }
97 ndigcl += compcl.size();
98 }
99 }
100 pc.outputs().snapshot({nm + "ctfrep", 0}, iosize);
101 mTimer.Stop();
102 LOGP(info, "Decoded {} {} in {} ROFs of {} streams ({}) in {}staggerd mode in {} s", ndigcl, mGetDigits ? "digits" : "clusters",
103 nrofs, nLayers, iosize.asString(), mDoStaggering ? "" : "non-", mTimer.CpuTime() - cput);
104}
105
106template <int N>
108{
109 LOGP(info, "{} Entropy Decoding total timing: Cpu: {:.3e} Real: {:.3e} s in {} slots",
110 Origin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
111}
112
113template <int N>
115{
116 std::string nm = ID.getName();
117 if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
118 if (mMaskNoise) {
119 pc.inputs().get<o2::itsmft::NoiseMap*>(nm + "noise");
120 }
121 if (mGetDigits || mMaskNoise) {
122 pc.inputs().get<o2::itsmft::TopologyDictionary*>(nm + "cldict");
123 }
124 }
125 pc.inputs().get<o2::itsmft::DPLAlpideParam<N>*>(nm + "alppar");
126 mCTFCoder.updateTimeDependentParams(pc, true);
127}
128
129template <int N>
131{
132 if (matcher == ConcreteDataMatcher(Origin, "NOISEMAP", 0)) {
133 mNoiseMap = (o2::itsmft::NoiseMap*)obj;
134 LOG(info) << Origin.as<std::string>() << " noise map updated";
135 return;
136 }
137 if (matcher == ConcreteDataMatcher(Origin, "CLUSDICT", 0)) {
138 LOG(info) << Origin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
139 mPattIdConverter.setDictionary((const TopologyDictionary*)obj);
140 return;
141 }
142 if (matcher == ConcreteDataMatcher(Origin, "ALPIDEPARAM", 0)) {
143 LOG(info) << "Alpide param updated";
144 return;
145 }
146 if (mCTFCoder.template finaliseCCDB<CTF>(matcher, obj)) {
147 return;
148 }
149}
150
151template <int N>
152DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
153{
156 uint32_t nLayers = doStag ? DPLAlpideParam<N>::getNLayers() : 1;
157
158 std::vector<InputSpec> inputs;
159 std::vector<OutputSpec> outputs;
160
161 // this produces weird memory problems in unrelated devices, to be understood
162 // outputs.emplace_back(OutputSpec{{"phystrig"}, Origin, "PHYSTRIG", 0, Lifetime::Timeframe});
163 std::string nm = ID.getName();
164 for (uint32_t iLayer = 0; iLayer < nLayers; ++iLayer) {
165 if (getDigits) {
166 outputs.emplace_back(OutputSpec{{nm + "Digits"}, Origin, "DIGITS", iLayer, Lifetime::Timeframe});
167 outputs.emplace_back(OutputSpec{{nm + "ROframes"}, Origin, "DIGITSROF", iLayer, Lifetime::Timeframe});
168 } else {
169 outputs.emplace_back(OutputSpec{{nm + "compClusters"}, Origin, "COMPCLUSTERS", iLayer, Lifetime::Timeframe});
170 outputs.emplace_back(OutputSpec{{nm + "ROframes"}, Origin, "CLUSTERSROF", iLayer, Lifetime::Timeframe});
171 outputs.emplace_back(OutputSpec{{nm + "patterns"}, Origin, "PATTERNS", iLayer, Lifetime::Timeframe});
172 }
173 inputs.emplace_back(EntropyDecoderSpec<N>::getBinding(nm + "CTF", iLayer), Origin, "CTFDATA", sspec * 100 + iLayer, Lifetime::Timeframe);
174 }
175 outputs.emplace_back(OutputSpec{{nm + "ctfrep"}, Origin, "CTFDECREP", 0, Lifetime::Timeframe});
176
177 inputs.emplace_back(nm + "alppar", Origin, "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Config/AlpideParam", Origin.as<std::string>())));
178 inputs.emplace_back(nm + "noise", Origin, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", Origin.as<std::string>())));
179 inputs.emplace_back(nm + "cldict", Origin, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", Origin.as<std::string>())));
180 if (ctfdictOpt.empty() || ctfdictOpt == "ccdb") {
181 inputs.emplace_back(std::string{"ctfdict_"} + ID.getName(), Origin, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", Origin.as<std::string>())));
182 }
183 inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
184
185 return DataProcessorSpec{
186 Origin == o2::header::gDataOriginITS ? "its-entropy-decoder" : "mft-entropy-decoder",
187 inputs,
188 outputs,
189 AlgorithmSpec{adaptFromTask<EntropyDecoderSpec<N>>(verbosity, doStag, getDigits, ctfdictOpt)},
190 Options{{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
191 {"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}},
192 {"ans-version", VariantType::String, {"version of ans entropy coder implementation to use"}}}};
193}
194
195framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
196{
197 return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
198}
199
200framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
201{
202 return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
203}
204
205} // namespace itsmft
206} // 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