Project
Loading...
Searching...
No Matches
CTFCoder.h
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
15
16#ifndef O2_TOF_CTFCODER_H
17#define O2_TOF_CTFCODER_H
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include "DataFormatsTOF/CTF.h"
25#include "TOFBase/Digit.h"
26
27class TTree;
28
29namespace o2
30{
31namespace tof
32{
33
35{
36 public:
37 CTFCoder(o2::ctf::CTFCoderBase::OpType op) : o2::ctf::CTFCoderBase(op, CTF::getNBlocks(), o2::detectors::DetID::TOF) {}
38 ~CTFCoder() final = default;
39
41 template <typename VEC>
42 o2::ctf::CTFIOSize encode(VEC& buff, const gsl::span<const ReadoutWindowData>& rofRecVec, const gsl::span<const Digit>& cdigVec, const gsl::span<const uint8_t>& pattVec);
43
45 template <typename VROF, typename VDIG, typename VPAT>
46 o2::ctf::CTFIOSize decode(const CTF::base& ec, VROF& rofRecVec, VDIG& cdigVec, VPAT& pattVec);
47
48 void createCoders(const std::vector<char>& bufVec, o2::ctf::CTFCoderBase::OpType op) final;
49
50 private:
52 void compress(CompressedInfos& cc, const gsl::span<const ReadoutWindowData>& rofRecVec, const gsl::span<const Digit>& cdigVec, const gsl::span<const uint8_t>& pattVec);
53 size_t estimateCompressedSize(const CompressedInfos& cc);
55 template <typename VROF, typename VDIG, typename VPAT>
56 void decompress(const CompressedInfos& cc, VROF& rofRecVec, VDIG& cdigVec, VPAT& pattVec);
57
58 void appendToTree(TTree& tree, CTF& ec);
59 void readFromTree(TTree& tree, int entry, std::vector<ReadoutWindowData>& rofRecVec, std::vector<Digit>& cdigVec, std::vector<uint8_t>& pattVec);
60};
61
64template <typename VEC>
65o2::ctf::CTFIOSize CTFCoder::encode(VEC& buff, const gsl::span<const ReadoutWindowData>& rofRecVec, const gsl::span<const Digit>& cdigVec, const gsl::span<const uint8_t>& pattVec)
66{
68 // what to do which each field: see o2::ctd::Metadata explanation
69 constexpr MD optField[CTF::getNBlocks()] = {
70 MD::EENCODE_OR_PACK, // BLCbcIncROF
71 MD::EENCODE_OR_PACK, // BLCorbitIncROF
72 MD::EENCODE_OR_PACK, // BLCndigROF
73 MD::EENCODE_OR_PACK, // BLCndiaROF
74 MD::EENCODE_OR_PACK, // BLCndiaCrate
75 MD::EENCODE_OR_PACK, // BLCtimeFrameInc
76 MD::EENCODE_OR_PACK, // BLCtimeTDCInc
77 MD::EENCODE_OR_PACK, // BLCstripID
78 MD::EENCODE_OR_PACK, // BLCchanInStrip
79 MD::EENCODE_OR_PACK, // BLCtot
80 MD::EENCODE_OR_PACK, // BLCpattMap
81 };
83 compress(cc, rofRecVec, cdigVec, pattVec);
84 // book output size with some margin
85 auto szIni = estimateCompressedSize(cc);
86 buff.resize(szIni);
87
88 auto ec = CTF::create(buff);
89 using ECB = CTF::base;
90
91 ec->setHeader(cc.header);
92 assignDictVersion(static_cast<o2::ctf::CTFDictHeader&>(ec->getHeader()));
93 ec->setANSHeader(mANSVersion);
94 // at every encoding the buffer might be autoexpanded, so we don't work with fixed pointer ec
95 o2::ctf::CTFIOSize iosize;
96#define ENCODETOF(part, slot, bits) CTF::get(buff.data())->encode(part, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
97 // clang-format off
98 iosize += ENCODETOF(cc.bcIncROF, CTF::BLCbcIncROF, 0);
99 iosize += ENCODETOF(cc.orbitIncROF, CTF::BLCorbitIncROF, 0);
100 iosize += ENCODETOF(cc.ndigROF, CTF::BLCndigROF, 0);
101 iosize += ENCODETOF(cc.ndiaROF, CTF::BLCndiaROF, 0);
102 iosize += ENCODETOF(cc.ndiaCrate, CTF::BLCndiaCrate, 0);
103 iosize += ENCODETOF(cc.timeFrameInc, CTF::BLCtimeFrameInc, 0);
104 iosize += ENCODETOF(cc.timeTDCInc, CTF::BLCtimeTDCInc, 0);
105 iosize += ENCODETOF(cc.stripID, CTF::BLCstripID, 0);
106 iosize += ENCODETOF(cc.chanInStrip, CTF::BLCchanInStrip, 0);
107 iosize += ENCODETOF(cc.tot, CTF::BLCtot, 0);
108 iosize += ENCODETOF(cc.pattMap, CTF::BLCpattMap, 0);
109 // clang-format on
110 CTF::get(buff.data())->print(getPrefix(), mVerbosity);
111 finaliseCTFOutput<CTF>(buff);
112 iosize.rawIn = sizeof(ReadoutWindowData) * rofRecVec.size() + sizeof(Digit) * cdigVec.size() + sizeof(uint8_t) * pattVec.size();
113 return iosize;
114}
115
118template <typename VROF, typename VDIG, typename VPAT>
119o2::ctf::CTFIOSize CTFCoder::decode(const CTF::base& ec, VROF& rofRecVec, VDIG& cdigVec, VPAT& pattVec)
120{
123 cc.header = ec.getHeader();
124 checkDictVersion(static_cast<const o2::ctf::CTFDictHeader&>(cc.header));
125 o2::ctf::CTFIOSize iosize;
126#define DECODETOF(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
127 // clang-format off
128 iosize += DECODETOF(cc.bcIncROF, CTF::BLCbcIncROF);
129 iosize += DECODETOF(cc.orbitIncROF, CTF::BLCorbitIncROF);
130 iosize += DECODETOF(cc.ndigROF, CTF::BLCndigROF);
131 iosize += DECODETOF(cc.ndiaROF, CTF::BLCndiaROF);
132 iosize += DECODETOF(cc.ndiaCrate, CTF::BLCndiaCrate);
133
134 iosize += DECODETOF(cc.timeFrameInc, CTF::BLCtimeFrameInc);
135 iosize += DECODETOF(cc.timeTDCInc, CTF::BLCtimeTDCInc);
136 iosize += DECODETOF(cc.stripID, CTF::BLCstripID);
137 iosize += DECODETOF(cc.chanInStrip, CTF::BLCchanInStrip);
138 iosize += DECODETOF(cc.tot, CTF::BLCtot);
139 iosize += DECODETOF(cc.pattMap, CTF::BLCpattMap);
140 // clang-format on
141 //
142 decompress(cc, rofRecVec, cdigVec, pattVec);
143 iosize.rawIn = sizeof(ReadoutWindowData) * rofRecVec.size() + sizeof(Digit) * cdigVec.size() + sizeof(uint8_t) * pattVec.size();
144 return iosize;
145}
148template <typename VROF, typename VDIG, typename VPAT>
149void CTFCoder::decompress(const CompressedInfos& cc, VROF& rofRecVec, VDIG& cdigVec, VPAT& pattVec)
150{
151 rofRecVec.resize(cc.header.nROFs);
152 cdigVec.resize(cc.header.nDigits);
153 pattVec.resize(cc.header.nPatternBytes);
154 std::vector<Digit> digCopy;
155
156 o2::InteractionRecord prevIR(cc.header.firstBC, cc.header.firstOrbit);
157 uint32_t firstEntry = 0, digCount = 0, stripCount = 0, ndiagnostic = 0;
158 for (uint32_t irof = 0; irof < cc.header.nROFs; irof++) {
159 // restore ROFRecord
160 auto& rofRec = rofRecVec[irof];
161 if (cc.orbitIncROF[irof]) { // new orbit
162 prevIR.bc = cc.bcIncROF[irof]; // bcInc has absolute meaning
163 prevIR.orbit += cc.orbitIncROF[irof];
164 } else {
165 prevIR.bc += cc.bcIncROF[irof];
166 }
167 rofRec.setBCData(prevIR);
168 rofRec.setFirstEntry(firstEntry);
169 rofRec.setNEntries(cc.ndigROF[irof]);
170 rofRec.setFirstEntryDia(ndiagnostic);
171 rofRec.setNEntriesDia(cc.ndiaROF[irof]);
172 for (int icrate = 0; icrate < 72; icrate++) {
173 rofRec.setDiagnosticInCrate(icrate, cc.ndiaCrate[irof * 72 + icrate] - 1); // -1 because number were traslated since (-1 means crate not available)
174 }
175 firstEntry += cc.ndigROF[irof];
176 ndiagnostic += cc.ndiaROF[irof];
177
178 if (!cc.ndigROF[irof]) {
179 continue;
180 }
181
182 // restore hit data
183 uint ctimeframe = 0;
184 uint ctdc = 0;
185
186 int firstDig = digCount;
187
188 int64_t BCrow = prevIR.toLong();
189
190 digCopy.resize(cc.ndigROF[irof]);
191 for (uint32_t idig = 0; idig < cc.ndigROF[irof]; idig++) {
192 auto& digit = digCopy[idig]; //cdigVec[digCount];
193 LOGF(debug, "%d) TF=%d, TDC=%d, STRIP=%d, CH=%d", idig, cc.timeFrameInc[digCount], cc.timeTDCInc[digCount], cc.stripID[digCount], cc.chanInStrip[digCount]);
194 if (cc.timeFrameInc[digCount]) { // new time frame
195 ctdc = cc.timeTDCInc[digCount];
196 ctimeframe += cc.timeFrameInc[digCount];
197 } else {
198 ctdc += cc.timeTDCInc[digCount];
199 }
200 LOGF(debug, "BC=%ld, TDC=%d, TOT=%d, CH=%d", uint32_t(ctimeframe) * 64 + ctdc / 1024 + BCrow, ctdc % 1024, cc.tot[digCount], uint32_t(cc.stripID[digCount]) * 96 + cc.chanInStrip[digCount]);
201
202 digit.setBC(uint32_t(ctimeframe) * 64 + ctdc / 1024 + BCrow);
203 digit.setTDC(ctdc % 1024);
204 digit.setTOT(cc.tot[digCount]);
205 digit.setChannel(uint32_t(cc.stripID[digCount]) * 96 + cc.chanInStrip[digCount]);
206
207 digCount++;
208 }
209
210 // sort digits according to strip number within the ROF
211 std::sort(digCopy.begin(), digCopy.end(),
213 int str1 = a.getChannel() / Geo::NPADS;
214 int str2 = b.getChannel() / Geo::NPADS;
215 if (str1 == str2) {
216 return (a.getOrderingKey() < b.getOrderingKey());
217 }
218 return (str1 < str2);
219 });
220
221 // fill digits, once sorted, of rof in digit vector
222 for (uint32_t idig = 0; idig < digCopy.size(); idig++) {
223 cdigVec[firstDig + idig] = digCopy[idig];
224 }
225
226 digCopy.clear();
227 }
228 // explicit patterns
229 memcpy(pattVec.data(), cc.pattMap.data(), cc.header.nPatternBytes); // RSTODO use swap?
230 assert(digCount == cc.header.nDigits);
231
232 if (digCount != cc.header.nDigits) {
233 LOG(error) << "expected " << cc.header.nDigits << " but counted " << digCount << " in ROFRecords";
234 throw std::runtime_error("mismatch between expected and counter number of digits");
235 }
236}
237
238} // namespace tof
239} // namespace o2
240
241#endif // O2_TOF_CTFCODER_H
Declarations for CTFCoderBase class (support of external dictionaries)
uint32_t op
Definitions for TOF CTF data.
#define DECODETOF(part, slot)
#define ENCODETOF(part, slot, bits)
std::ostringstream debug
void checkDictVersion(const CTFDictHeader &h) const
ctf::ANSHeader mANSVersion
std::string getPrefix() const
virtual void assignDictVersion(CTFDictHeader &h) const
<<======================== Auxiliary classes =======================<<
static auto get(void *head)
cast arbitrary buffer head to container class. Head is supposed to respect the alignment
const H & getHeader() const
void print(const std::string &prefix="", int verbosity=1) const
print itself
EncodedBlocks< CTFHeader, N, uint32_t > base
static auto create(void *head, size_t sz)
create container from arbitrary buffer of predefined size (in bytes!!!). Head is supposed to respect ...
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
~CTFCoder() final=default
CTFCoder(o2::ctf::CTFCoderBase::OpType op)
Definition CTFCoder.h:37
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const ReadoutWindowData > &rofRecVec, const gsl::span< const Digit > &cdigVec, const gsl::span< const uint8_t > &pattVec)
entropy-encode clusters to buffer with CTF
Definition CTFCoder.h:65
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
Definition CTFCoder.cxx:150
o2::ctf::CTFIOSize decode(const CTF::base &ec, VROF &rofRecVec, VDIG &cdigVec, VPAT &pattVec)
entropy decode clusters from buffer with CTF
Definition CTFCoder.h:119
TOF digit implementation.
Definition Digit.h:31
GLuint entry
Definition glcorearb.h:5735
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
return(kp2 - aa - bb) *kp1/aa
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
Detector header base.
wrapper for the Entropy-encoded clusters of the TF
Definition CTF.h:81
@ BLCndiaCrate
Definition CTF.h:88
@ BLCtimeFrameInc
Definition CTF.h:89
@ BLCorbitIncROF
Definition CTF.h:85
@ BLCndigROF
Definition CTF.h:86
@ BLCtimeTDCInc
Definition CTF.h:90
@ BLCtot
Definition CTF.h:93
@ BLCchanInStrip
Definition CTF.h:92
@ BLCbcIncROF
Definition CTF.h:84
@ BLCstripID
Definition CTF.h:91
@ BLCndiaROF
Definition CTF.h:87
@ BLCpattMap
Definition CTF.h:94
Compressed but not yet entropy-encoded infos.
Definition CTF.h:43
std::vector< o2::mch::ChannelCode > cc
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::vector< unsigned char > pattVec