Project
Loading...
Searching...
No Matches
CTFCoder.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
15
18#include <TTree.h>
19
20using namespace o2::tof;
21
23// Register encoded data in the tree (Fill is not called, will be done by caller)
24void CTFCoder::appendToTree(TTree& tree, CTF& ec)
25{
27}
28
30// extract and decode data from the tree
31void CTFCoder::readFromTree(TTree& tree, int entry, std::vector<ReadoutWindowData>& rofRecVec, std::vector<Digit>& cdigVec, std::vector<uint8_t>& pattVec)
32{
33 assert(entry >= 0 && entry < tree.GetEntries());
34 CTF ec;
36 decode(ec, rofRecVec, cdigVec, pattVec);
37}
38
40void CTFCoder::compress(CompressedInfos& cc,
41 const gsl::span<const ReadoutWindowData>& rofRecVec,
42 const gsl::span<const Digit>& cdigVec,
43 const gsl::span<const uint8_t>& pattVec)
44{
45 // store in the header the orbit of 1st ROF
46 cc.clear();
47 cc.header.det = mDet;
48 if (!rofRecVec.size()) {
49 return;
50 }
51 std::vector<Digit> digCopy;
52 int ndigTot = 0, nrofTot = 0, nrofIni = rofRecVec.size(), ndigIni = cdigVec.size();
53 uint16_t prevBC = 0;
54 uint32_t prevOrbit = 0;
55 LOGF(debug, "TOF compress %d ReadoutWindow with %ld digits", nrofIni, ndigIni);
56 if (!mIRFrameSelector.isSet()) {
57 cc.bcIncROF.reserve(nrofIni);
58 cc.orbitIncROF.reserve(nrofIni);
59 cc.ndigROF.reserve(nrofIni);
60 cc.ndiaROF.reserve(nrofIni);
61 cc.ndiaCrate.reserve(nrofIni * 72);
62
63 cc.timeFrameInc.reserve(ndigIni);
64 cc.timeTDCInc.reserve(ndigIni);
65 cc.stripID.reserve(ndigIni);
66 cc.chanInStrip.reserve(ndigIni);
67 cc.tot.reserve(ndigIni);
68 }
69
70 for (int rof0 = 0; rof0 < nrofIni; rof0++) {
71 const auto& rofRec = rofRecVec[rof0];
72 const auto ir = rofRec.getBCData();
73 if (mIRFrameSelector.isSet() && mIRFrameSelector.check(o2::dataformats::IRFrame{ir, ir + (o2::constants::lhc::LHCMaxBunches / 3 - 1)}) < 0) {
74 continue;
75 }
76 int64_t rofInBC = ir.toLong();
77 digCopy.clear(); // make a copy of digits
78 int ndig = rofRec.size(), idigMin = rofRec.first(), idigMax = idigMin + ndig;
79 for (int idig = idigMin; idig < idigMax; idig++) {
80 digCopy.push_back(cdigVec[idig]);
81 }
82 // sort digits according to time (ascending order)
83 std::sort(digCopy.begin(), digCopy.end(), [](o2::tof::Digit a, o2::tof::Digit b) { return (a.getBC() == b.getBC()) ? (a.getTDC() < b.getTDC()) : a.getBC() < b.getBC(); });
84
85 int timeframe = 0, tdc = 0, ndigAcc = 0;
86 for (int idig = idigMin; idig < idigMax; idig++) {
87 const auto& dig = digCopy[idig - idigMin];
88 if (mIRFrameSelector.isSet() && mIRFrameSelector.check(dig.getIR()) < 0) {
89 continue;
90 }
91 ndigAcc++;
92 int deltaBC = dig.getBC() - rofInBC;
93 int ctimeframe = deltaBC / 64;
94 int cTDC = (deltaBC % 64) * 1024 + dig.getTDC();
95 if (ctimeframe == timeframe) {
96 cc.timeFrameInc.push_back(0);
97 cc.timeTDCInc.push_back(cTDC - tdc);
98 } else {
99 cc.timeFrameInc.push_back(ctimeframe - timeframe);
100 cc.timeTDCInc.push_back(cTDC);
101 timeframe = ctimeframe;
102 }
103 tdc = cTDC;
104
105 int chan = dig.getChannel();
106 cc.stripID.push_back(chan / Geo::NPADS);
107 cc.chanInStrip.push_back(chan % Geo::NPADS);
108 cc.tot.push_back(dig.getTOT());
109 LOGF(debug, "%d) TOFBC = %d, deltaBC = %d, TDC = %d, CH=%d", nrofTot, rofInBC, deltaBC, cTDC, chan);
110 LOGF(debug, "%d) TF=%d, TDC=%d, STRIP=%d, CH=%d, TOT=%d", idig, cc.timeFrameInc[idig], cc.timeTDCInc[idig], cc.stripID[idig], cc.chanInStrip[idig], cc.tot[idig]);
111 }
112 ndigTot += ndigAcc;
113 if (ndigAcc || !mIRFrameSelector.isSet()) {
114 if (nrofTot == 0) { // very 1st ROF
115 prevOrbit = cc.header.firstOrbit = ir.orbit;
116 prevBC = cc.header.firstBC = ir.bc;
117 }
118 if (ir.orbit == prevOrbit) {
119 cc.orbitIncROF.push_back(0);
120 cc.bcIncROF.push_back(ir.bc - prevBC); // store increment of BC if in the same orbit
121 } else {
122 cc.orbitIncROF.push_back(ir.orbit - prevOrbit);
123 cc.bcIncROF.push_back(ir.bc); // otherwise, store absolute bc
124 prevOrbit = ir.orbit;
125 }
126 cc.ndigROF.push_back(ndigAcc);
127 cc.ndiaROF.push_back(rofRec.sizeDia());
128 cc.ndiaCrate.reserve(cc.ndiaCrate.size() + 72);
129 for (int icrate = 0; icrate < 72; icrate++) {
130 if (rofRec.isEmptyCrate(icrate)) {
131 cc.ndiaCrate.push_back(0);
132 } else {
133 cc.ndiaCrate.push_back(rofRec.getDiagnosticInCrate(icrate) + 1); // shifted by one since -1 means crate not available (then to get unsigned int)
134 }
135 }
136 prevBC = ir.bc;
137 nrofTot++;
138 }
139 } // loop over ROFs
140 if (nrofTot) {
141 cc.header.nROFs = nrofTot;
142 cc.header.nDigits = ndigTot;
143 cc.header.nPatternBytes = pattVec.size();
144 cc.pattMap.resize(cc.header.nPatternBytes);
145 memcpy(cc.pattMap.data(), pattVec.data(), cc.header.nPatternBytes); // RSTODO: do we need this?
146 }
147}
148
150void CTFCoder::createCoders(const std::vector<char>& bufVec, o2::ctf::CTFCoderBase::OpType op)
151{
152 const auto ctf = CTF::getImage(bufVec.data());
153 CompressedInfos cc; // just to get member types
154#define MAKECODER(part, slot) createCoder(op, std::get<rans::RenormedDenseHistogram<decltype(part)::value_type>>(ctf.getDictionary<decltype(part)::value_type>(slot, mANSVersion)), int(slot))
155 // clang-format off
156 MAKECODER(cc.bcIncROF, CTF::BLCbcIncROF);
157 MAKECODER(cc.orbitIncROF, CTF::BLCorbitIncROF);
158 MAKECODER(cc.ndigROF, CTF::BLCndigROF);
159 MAKECODER(cc.ndiaROF, CTF::BLCndiaROF);
160 MAKECODER(cc.ndiaCrate, CTF::BLCndiaCrate);
161
162 MAKECODER(cc.timeFrameInc, CTF::BLCtimeFrameInc);
163 MAKECODER(cc.timeTDCInc, CTF::BLCtimeTDCInc);
164 MAKECODER(cc.stripID, CTF::BLCstripID);
165 MAKECODER(cc.chanInStrip, CTF::BLCchanInStrip);
167 MAKECODER(cc.pattMap, CTF::BLCpattMap);
168 // clang-format on
169}
170
172size_t CTFCoder::estimateCompressedSize(const CompressedInfos& cc)
173{
174 size_t sz = 0;
175 // RS FIXME this is very crude estimate, instead, an empirical values should be used
176
177 sz += estimateBufferSize(static_cast<int>(CTF::BLCbcIncROF), cc.bcIncROF);
178 sz += estimateBufferSize(static_cast<int>(CTF::BLCorbitIncROF), cc.orbitIncROF);
179 sz += estimateBufferSize(static_cast<int>(CTF::BLCndigROF), cc.ndigROF);
180 sz += estimateBufferSize(static_cast<int>(CTF::BLCndiaROF), cc.ndiaROF);
181 sz += estimateBufferSize(static_cast<int>(CTF::BLCndiaCrate), cc.ndiaCrate);
182 sz += estimateBufferSize(static_cast<int>(CTF::BLCtimeFrameInc), cc.timeFrameInc);
183 sz += estimateBufferSize(static_cast<int>(CTF::BLCtimeTDCInc), cc.timeTDCInc);
184 sz += estimateBufferSize(static_cast<int>(CTF::BLCstripID), cc.stripID);
185 sz += estimateBufferSize(static_cast<int>(CTF::BLCchanInStrip), cc.chanInStrip);
186 sz += estimateBufferSize(static_cast<int>(CTF::BLCtot), cc.tot);
187 sz += estimateBufferSize(static_cast<int>(CTF::BLCpattMap), cc.pattMap);
188 sz *= 2. / 3; // if needed, will be autoexpanded
189 LOG(debug) << "Estimated output size is " << sz << " bytes";
190 return sz;
191}
#define MAKECODER(part, slot)
uint32_t op
class for entropy encoding/decoding of TOF compressed infos data
std::ostringstream debug
size_t estimateBufferSize(size_t slot, source_IT samplesBegin, source_IT samplesEnd)
o2::utils::IRFrameSelector mIRFrameSelector
void readFromTree(TTree &tree, const std::string &name, int ev=0)
read from tree to non-flat object
static auto getImage(const void *newHead)
get const image of the container wrapper, with pointers in the image relocated to new head
size_t appendToTree(TTree &tree, const std::string &name) const
attach to tree
static constexpr const char * getName(ID id)
names of defined detectors
Definition DetID.h:145
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
static constexpr Int_t NPADS
Definition Geo.h:110
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
GLuint entry
Definition glcorearb.h:5735
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
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"
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::vector< unsigned char > pattVec