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
24
25using namespace o2::framework;
26
27namespace o2
28{
29namespace itsmft
30{
31EntropyDecoderSpec::EntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits, const std::string& ctfdictOpt)
32 : mOrigin(orig), mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, orig == o2::header::gDataOriginITS ? o2::detectors::DetID::ITS : o2::detectors::DetID::MFT, ctfdictOpt), mGetDigits(getDigits)
33{
35 mDetPrefix = orig == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
36 mTimer.Stop();
37 mTimer.Reset();
38 mCTFCoder.setVerbosity(verbosity);
39 mCTFCoder.setDictBinding(std::string("ctfdict") + mDetPrefix);
40}
41
43{
44 mCTFCoder.init<CTF>(ic);
45 mMaskNoise = ic.options().get<bool>("mask-noise");
46 mUseClusterDictionary = !ic.options().get<bool>("ignore-cluster-dictionary");
47}
48
50{
52 mTimer.Reset();
53 }
54 auto cput = mTimer.CpuTime();
55 mTimer.Start(false);
56 o2::ctf::CTFIOSize iosize;
57 updateTimeDependentParams(pc);
58 auto buff = pc.inputs().get<gsl::span<o2::ctf::BufferType>>(std::string("ctf") + mDetPrefix);
59 // since the buff is const, we cannot use EncodedBlocks::relocate directly, instead we wrap its data to another flat object
60 // const auto ctfImage = o2::itsmft::CTF::getImage(buff.data());
61
62 // this produces weird memory problems in unrelated devices, to be understood
63 // auto& trigs = pc.outputs().make<std::vector<o2::itsmft::PhysTrigger>>(OutputRef{"phystrig"}); // dummy output
64
65 auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(OutputRef{"ROframes"});
66 if (mGetDigits) {
67 auto& digits = pc.outputs().make<std::vector<o2::itsmft::Digit>>(OutputRef{"Digits"});
68 if (buff.size()) {
69 iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, digits, mNoiseMap, mPattIdConverter);
70 }
71 mTimer.Stop();
72 LOG(info) << "Decoded " << digits.size() << " digits in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
73 } else {
74 auto& compcl = pc.outputs().make<std::vector<o2::itsmft::CompClusterExt>>(OutputRef{"compClusters"});
75 auto& patterns = pc.outputs().make<std::vector<unsigned char>>(OutputRef{"patterns"});
76 if (buff.size()) {
77 iosize = mCTFCoder.decode(o2::itsmft::CTF::getImage(buff.data()), rofs, compcl, patterns, mNoiseMap, mPattIdConverter);
78 }
79 mTimer.Stop();
80 LOG(info) << "Decoded " << compcl.size() << " clusters in " << rofs.size() << " RO frames, (" << iosize.asString() << ") in " << mTimer.CpuTime() - cput << " s";
81 }
82 pc.outputs().snapshot({"ctfrep", 0}, iosize);
83}
84
86{
87 LOGF(info, "%s Entropy Decoding total timing: Cpu: %.3e Real: %.3e s in %d slots",
88 mOrigin.as<std::string>(), mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
89}
90
91void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
92{
93 if (pc.services().get<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
94 if (mMaskNoise) {
95 pc.inputs().get<o2::itsmft::NoiseMap*>(std::string("noise") + mDetPrefix);
96 }
97 if (mGetDigits || mMaskNoise) {
98 pc.inputs().get<o2::itsmft::TopologyDictionary*>(std::string("cldict") + mDetPrefix);
99 }
100 }
101 mCTFCoder.updateTimeDependentParams(pc, true);
102}
103
105{
106 if (matcher == ConcreteDataMatcher(mOrigin, "NOISEMAP", 0)) {
107 mNoiseMap = (o2::itsmft::NoiseMap*)obj;
108 LOG(info) << mOrigin.as<std::string>() << " noise map updated";
109 return;
110 }
111 if (matcher == ConcreteDataMatcher(mOrigin, "CLUSDICT", 0)) {
112 LOG(info) << mOrigin.as<std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : "");
113 mPattIdConverter.setDictionary((const TopologyDictionary*)obj);
114 return;
115 }
116 if (mCTFCoder.finaliseCCDB<CTF>(matcher, obj)) {
117 return;
118 }
119}
120
121DataProcessorSpec getEntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
122{
123 std::vector<OutputSpec> outputs;
124 // this is a special dummy input which makes sense only in sync workflows
125
126 // this produces weird memory problems in unrelated devices, to be understood
127 // outputs.emplace_back(OutputSpec{{"phystrig"}, orig, "PHYSTRIG", 0, Lifetime::Timeframe});
128
129 if (getDigits) {
130 outputs.emplace_back(OutputSpec{{"Digits"}, orig, "DIGITS", 0, Lifetime::Timeframe});
131 outputs.emplace_back(OutputSpec{{"ROframes"}, orig, "DIGITSROF", 0, Lifetime::Timeframe});
132 } else {
133 outputs.emplace_back(OutputSpec{{"compClusters"}, orig, "COMPCLUSTERS", 0, Lifetime::Timeframe});
134 outputs.emplace_back(OutputSpec{{"ROframes"}, orig, "CLUSTERSROF", 0, Lifetime::Timeframe});
135 outputs.emplace_back(OutputSpec{{"patterns"}, orig, "PATTERNS", 0, Lifetime::Timeframe});
136 }
137 outputs.emplace_back(OutputSpec{{"ctfrep"}, orig, "CTFDECREP", 0, Lifetime::Timeframe});
138 std::string nm = orig == o2::header::gDataOriginITS ? "_ITS" : "_MFT";
139 std::vector<InputSpec> inputs;
140 inputs.emplace_back(std::string("ctf") + nm, orig, "CTFDATA", sspec, Lifetime::Timeframe);
141 inputs.emplace_back(std::string("noise") + nm, orig, "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/NoiseMap", orig.as<std::string>())));
142 inputs.emplace_back(std::string("cldict") + nm, orig, "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/ClusterDictionary", orig.as<std::string>())));
143 if (ctfdictOpt.empty() || ctfdictOpt == "ccdb") {
144 inputs.emplace_back(std::string("ctfdict") + nm, orig, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", orig.as<std::string>())));
145 }
146 inputs.emplace_back(std::string("trigoffset"), "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
147
148 return DataProcessorSpec{
150 inputs,
151 outputs,
152 AlgorithmSpec{adaptFromTask<EntropyDecoderSpec>(orig, verbosity, getDigits, ctfdictOpt)},
153 Options{{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
154 {"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}},
155 {"ans-version", VariantType::String, {"version of ans entropy coder implementation to use"}}}};
156}
157} // namespace itsmft
158} // 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.
void updateTimeDependentParams(o2::framework::ProcessingContext &pc, bool askTree=false)
void setDictBinding(const std::string &s)
void init(o2::framework::InitContext &ic)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
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
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.
o2::ctf::CTFIOSize decode(const CTF::base &ec, VROF &rofRecVec, VCLUS &cclusVec, VPAT &pattVec, const NoiseMap *noiseMap, const LookUp &clPattLookup)
entropy decode clusters from buffer with CTF
Definition CTFCoder.h:140
EntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, bool getDigits=false, const std::string &ctfdictOpt="none")
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
static auto getName(o2::header::DataOrigin orig)
void run(o2::framework::ProcessingContext &pc) final
void init(o2::framework::InitContext &ic) final
void setDictionary(const TopologyDictionary *dict)
Definition LookUp.cxx:42
NoiseMap class for the ITS and MFT.
Definition NoiseMap.h:39
constexpr o2::header::DataOrigin gDataOriginMFT
Definition DataHeader.h:572
constexpr o2::header::DataOrigin gDataOriginITS
Definition DataHeader.h:570
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
framework::DataProcessorSpec getEntropyDecoderSpec(o2::header::DataOrigin orig, int verbosity, 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
std::enable_if_t< std::is_same< T, std::string >::value==true, T > as() const
get the descriptor as std::string
Definition DataHeader.h:301
wrapper for the Entropy-encoded clusters of the TF
Definition CTF.h:69
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits