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_ZDC_CTFCODER_H
17#define O2_ZDC_CTFCODER_H
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include <array>
23#include "DataFormatsZDC/CTF.h"
27
28class TTree;
29
30namespace o2
31{
32namespace zdc
33{
34
36{
37 public:
38 CTFCoder(o2::ctf::CTFCoderBase::OpType op) : o2::ctf::CTFCoderBase(op, CTF::getNBlocks(), o2::detectors::DetID::ZDC) {}
39 ~CTFCoder() final = default;
40
42 template <typename VEC>
43 o2::ctf::CTFIOSize encode(VEC& buff, const gsl::span<const BCData>& trgData, const gsl::span<const ChannelData>& chanData, const gsl::span<const OrbitData>& pedData);
44
46 template <typename VTRG, typename VCHAN, typename VPED>
47 o2::ctf::CTFIOSize decode(const CTF::base& ec, VTRG& trigVec, VCHAN& chanVec, VPED& pedVec);
48
49 void createCoders(const std::vector<char>& bufVec, o2::ctf::CTFCoderBase::OpType op) final;
50
51 void setBCShiftOrbits(long v) { mBCShiftOrbits = v; }
52 auto getBCShiftOrbits() const { return mBCShiftOrbits; }
53
54 private:
55 template <typename VEC>
56 o2::ctf::CTFIOSize encode_impl(VEC& buff, const gsl::span<const BCData>& trgData, const gsl::span<const ChannelData>& chanData, const gsl::span<const OrbitData>& pedData);
57 void appendToTree(TTree& tree, CTF& ec);
58 void readFromTree(TTree& tree, int entry, std::vector<BCData>& trigVec, std::vector<ChannelData>& chanVec, std::vector<OrbitData>& pedVec);
59 std::vector<BCData> mTrgDataFilt;
60 std::vector<ChannelData> mChanDataFilt;
61 std::vector<OrbitData> mPedDataFilt;
62 int64_t mBCShiftOrbits = 0; // integer orbit shift (in BCs) corresponding to mBCShift. Since BCs 0 and 3563 should not be changed, this value will be used for them
63};
64
66template <typename VEC>
67o2::ctf::CTFIOSize CTFCoder::encode(VEC& buff, const gsl::span<const BCData>& trigData, const gsl::span<const ChannelData>& chanData, const gsl::span<const OrbitData>& pedData)
68{
69 if (mIRFrameSelector.isSet()) { // preselect data
70 std::unordered_map<uint32_t, int> orbitSaved;
71 mTrgDataFilt.clear();
72 mChanDataFilt.clear();
73 mPedDataFilt.clear();
74 for (const auto& trig : trigData) {
75 if (mIRFrameSelector.check(trig.ir) >= 0) {
76 mTrgDataFilt.push_back(trig);
77 auto chanIt = chanData.begin() + trig.ref.getFirstEntry();
78 auto& trigC = mTrgDataFilt.back();
79 trigC.ref.set((int)mChanDataFilt.size(), trig.ref.getEntries());
80 std::copy(chanIt, chanIt + trig.ref.getEntries(), std::back_inserter(mChanDataFilt));
81 orbitSaved[trig.ir.orbit]++;
82 }
83 }
84 // collect saved orbits data
85 for (const auto& ped : pedData) {
86 if (orbitSaved.find(ped.ir.orbit) != orbitSaved.end()) {
87 mPedDataFilt.push_back(ped);
88 }
89 }
90 return encode_impl(buff, mTrgDataFilt, mChanDataFilt, mPedDataFilt);
91 }
92 return encode_impl(buff, trigData, chanData, pedData);
93}
94
95template <typename VEC>
96o2::ctf::CTFIOSize CTFCoder::encode_impl(VEC& buff, const gsl::span<const BCData>& trigData, const gsl::span<const ChannelData>& chanData, const gsl::span<const OrbitData>& pedData)
97{
99 // what to do which each field: see o2::ctd::Metadata explanation
100 constexpr MD optField[CTF::getNBlocks()] = {
101 MD::EENCODE_OR_PACK, // _bcIncTrig
102 MD::EENCODE_OR_PACK, // _orbitIncTrig,
103 MD::EENCODE_OR_PACK, // _moduleTrig,
104 MD::EENCODE_OR_PACK, // _channelsHL,
105 MD::EENCODE_OR_PACK, // _triggersHL,
106 MD::EENCODE_OR_PACK, // _extTriggers,
107 MD::EENCODE_OR_PACK, // _nchanTrig,
108 //
109 MD::EENCODE_OR_PACK, // _chanID,
110 MD::EENCODE_OR_PACK, // _chanData,
111 //
112 MD::EENCODE_OR_PACK, // _orbitIncEOD,
113 MD::EENCODE_OR_PACK, // _pedData
114 MD::EENCODE_OR_PACK, // _sclInc
115 };
116
117 CTFHelper helper(trigData, chanData, pedData);
118
119 // book output size with some margin
120 auto szIni = sizeof(CTFHeader) + helper.getSize() * 2. / 3; // will be autoexpanded if needed
121 buff.resize(szIni);
122
123 auto ec = CTF::create(buff);
124 using ECB = CTF::base;
125
126 ec->setHeader(helper.createHeader());
127 assignDictVersion(static_cast<o2::ctf::CTFDictHeader&>(ec->getHeader()));
128 ec->setANSHeader(mANSVersion);
129 // at every encoding the buffer might be autoexpanded, so we don't work with fixed pointer ec
130 o2::ctf::CTFIOSize iosize;
131#define ENCODEZDC(beg, end, slot, bits) CTF::get(buff.data())->encode(beg, end, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
132 // clang-format off
133 iosize += ENCODEZDC(helper.begin_bcIncTrig(), helper.end_bcIncTrig(), CTF::BLC_bcIncTrig, 0);
134 iosize += ENCODEZDC(helper.begin_orbitIncTrig(), helper.end_orbitIncTrig(), CTF::BLC_orbitIncTrig, 0);
135 iosize += ENCODEZDC(helper.begin_moduleTrig(), helper.end_moduleTrig(), CTF::BLC_moduleTrig, 0);
136 iosize += ENCODEZDC(helper.begin_channelsHL(), helper.end_channelsHL(), CTF::BLC_channelsHL, 0);
137 iosize += ENCODEZDC(helper.begin_triggersHL(), helper.end_triggersHL(), CTF::BLC_triggersHL, 0);
138 iosize += ENCODEZDC(helper.begin_extTriggers(), helper.end_extTriggers(), CTF::BLC_extTriggers, 0);
139 iosize += ENCODEZDC(helper.begin_nchanTrig(), helper.end_nchanTrig(), CTF::BLC_nchanTrig, 0);
140 //
141 iosize += ENCODEZDC(helper.begin_chanID(), helper.end_chanID(), CTF::BLC_chanID, 0);
142 iosize += ENCODEZDC(helper.begin_chanData(), helper.end_chanData(), CTF::BLC_chanData, 0);
143 //
144 iosize += ENCODEZDC(helper.begin_orbitIncEOD(), helper.end_orbitIncEOD(), CTF::BLC_orbitIncEOD, 0);
145 iosize += ENCODEZDC(helper.begin_pedData(), helper.end_pedData(), CTF::BLC_pedData, 0);
146 iosize += ENCODEZDC(helper.begin_sclInc(), helper.end_sclInc(), CTF::BLC_sclInc, 0);
147
148 // clang-format on
149 CTF::get(buff.data())->print(getPrefix(), mVerbosity);
150 finaliseCTFOutput<CTF>(buff);
151 iosize.rawIn = sizeof(BCData) * trigData.size() + sizeof(ChannelData) * chanData.size() + sizeof(OrbitData) * pedData.size();
152 return iosize;
153}
154
156template <typename VTRG, typename VCHAN, typename VPED>
157o2::ctf::CTFIOSize CTFCoder::decode(const CTF::base& ec, VTRG& trigVec, VCHAN& chanVec, VPED& pedVec)
158{
159 auto header = ec.getHeader();
160 checkDictVersion(static_cast<const o2::ctf::CTFDictHeader&>(header));
162 std::vector<int16_t> bcIncTrig, scalerInc;
163 std::vector<int32_t> orbitIncTrig, orbitIncEOD;
164 std::vector<uint16_t> moduleTrig, nchanTrig, chanData, pedData, triggersHL, channelsHL;
165 std::vector<uint8_t> extTriggers, chanID;
166
167 o2::ctf::CTFIOSize iosize;
168#define DECODEZDC(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
169 // clang-format off
170 iosize += DECODEZDC(bcIncTrig, CTF::BLC_bcIncTrig);
171 iosize += DECODEZDC(orbitIncTrig, CTF::BLC_orbitIncTrig);
172 iosize += DECODEZDC(moduleTrig, CTF::BLC_moduleTrig);
173 iosize += DECODEZDC(channelsHL, CTF::BLC_channelsHL);
174 iosize += DECODEZDC(triggersHL, CTF::BLC_triggersHL);
175 iosize += DECODEZDC(extTriggers, CTF::BLC_extTriggers);
176 iosize += DECODEZDC(nchanTrig, CTF::BLC_nchanTrig);
177 //
178 iosize += DECODEZDC(chanID, CTF::BLC_chanID);
179 iosize += DECODEZDC(chanData, CTF::BLC_chanData);
180 //
181 iosize += DECODEZDC(orbitIncEOD, CTF::BLC_orbitIncEOD);
182 iosize += DECODEZDC(pedData, CTF::BLC_pedData);
183 iosize += DECODEZDC(scalerInc, CTF::BLC_sclInc);
184 // clang-format on
185 //
186 trigVec.clear();
187 chanVec.clear();
188 pedVec.clear();
189 trigVec.reserve(header.nTriggers);
190 chanVec.reserve(header.nChannels);
191 pedVec.reserve(header.nEOData);
192
193 // triggers and channels
194 uint32_t firstEntry = 0;
195 o2::InteractionRecord ir(header.firstBC, header.firstOrbit);
196 auto chanDataIt = chanData.begin();
197 auto chanIdIt = chanID.begin();
198 auto modTrigIt = moduleTrig.begin();
199 auto pedValIt = pedData.begin();
200 auto sclIncIt = scalerInc.begin();
201 auto channelsHLIt = channelsHL.begin();
202 auto triggersHLIt = triggersHL.begin();
203 auto scalers = header.firstScaler;
204 bool checkIROK = (mBCShift == 0); // need to check if CTP offset correction does not make the local time negative ?
205 for (uint32_t itrig = 0; itrig < header.nTriggers; itrig++) {
206 // restore TrigRecord
207 if (orbitIncTrig[itrig]) { // non-0 increment => new orbit
208 ir.bc = bcIncTrig[itrig]; // bcInc has absolute meaning
209 ir.orbit += orbitIncTrig[itrig];
210 } else {
211 ir.bc += bcIncTrig[itrig];
212 }
213 long bcshift = 0;
214 if (mBCShift) {
215 bcshift = (ir.bc == 0 || ir.bc == o2::constants::lhc::LHCMaxBunches - 1) ? mBCShiftOrbits : mBCShift; // we should never touch the BC of BC=0 or 3563
216 }
217 if (checkIROK || canApplyBCShift(ir, bcshift)) { // correction will be ok
218 checkIROK = true;
219 } else { // correction would make IR prior to mFirstTFOrbit, skip
220 chanDataIt += NTimeBinsPerBC * nchanTrig[itrig];
221 chanIdIt += nchanTrig[itrig];
222 channelsHLIt += 2;
223 triggersHLIt += 2;
224 continue;
225 }
226 auto firstChanEntry = chanVec.size();
227 for (uint16_t ic = 0; ic < nchanTrig[itrig]; ic++) {
228 auto& chan = chanVec.emplace_back();
229 chan.id = *chanIdIt++;
230 std::copy_n(chanDataIt, NTimeBinsPerBC, chan.data.begin());
231 chanDataIt += NTimeBinsPerBC;
232 }
233 uint32_t chHL = (uint32_t(*channelsHLIt++) << 16) + *channelsHLIt++;
234 uint32_t trHL = (uint32_t(*triggersHLIt++) << 16) + *triggersHLIt++;
235
236 auto& bcTrig = trigVec.emplace_back(firstChanEntry, chanVec.size() - firstChanEntry, ir - bcshift, chHL, trHL, extTriggers[itrig]);
237 std::copy_n(modTrigIt, NModules, bcTrig.moduleTriggers.begin());
238 modTrigIt += NModules;
239 }
240
241 // pedestal data
242 ir = {o2::constants::lhc::LHCMaxBunches - 1, header.firstOrbitEOData};
243 for (uint32_t ip = 0; ip < header.nEOData; ip++) {
244 ir.orbit += orbitIncEOD[ip];
245 long bcshift = 0;
246 if (mBCShift) {
247 bcshift = (ir.bc == 0 || ir.bc == o2::constants::lhc::LHCMaxBunches - 1) ? mBCShiftOrbits : mBCShift; // we should never touch the BC of BC=0 or 3563
248 }
249 if (checkIROK || canApplyBCShift(ir, bcshift)) { // correction will be ok
250 checkIROK = true;
251 } else { // correction would make IR prior to mFirstTFOrbit, skip
252 sclIncIt += NChannels;
253 pedValIt += NChannels;
254 continue;
255 }
256 for (uint32_t ic = 0; ic < NChannels; ic++) {
257 scalers[ic] += *sclIncIt++; // increment scaler
258 }
259 auto& ped = pedVec.emplace_back(OrbitData{ir - bcshift, {}, scalers});
260 std::copy_n(pedValIt, NChannels, ped.data.begin());
261 pedValIt += NChannels;
262 }
263 // make sure whole data was used
264 assert(chanDataIt == chanData.end());
265 assert(chanIdIt == chanID.end());
266 assert(modTrigIt == moduleTrig.end());
267 assert(pedValIt == pedData.end());
268 assert(channelsHLIt == channelsHL.end());
269 assert(triggersHLIt == triggersHL.end());
270 assert(sclIncIt == scalerInc.end());
271 iosize.rawIn = sizeof(BCData) * trigVec.size() + sizeof(ChannelData) * chanVec.size() + sizeof(OrbitData) * pedVec.size();
272 return iosize;
273}
274
275} // namespace zdc
276} // namespace o2
277
278#endif // O2_ZDC_CTFCODER_H
Declarations for CTFCoderBase class (support of external dictionaries)
uint32_t op
Definitions for ZDC CTF data.
#define ENCODEZDC(beg, end, slot, bits)
#define DECODEZDC(part, slot)
Helper for ZDC CTF creation.
void checkDictVersion(const CTFDictHeader &h) const
ctf::ANSHeader mANSVersion
std::string getPrefix() const
o2::utils::IRFrameSelector mIRFrameSelector
virtual void assignDictVersion(CTFDictHeader &h) const
bool canApplyBCShift(const o2::InteractionRecord &ir, long shift) 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
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
CTFCoder(o2::ctf::CTFCoderBase::OpType op)
Definition CTFCoder.h:38
~CTFCoder() final=default
void setBCShiftOrbits(long v)
Definition CTFCoder.h:51
o2::ctf::CTFIOSize decode(const CTF::base &ec, VTRG &trigVec, VCHAN &chanVec, VPED &pedVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:157
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
Definition CTFCoder.cxx:40
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const BCData > &trgData, const gsl::span< const ChannelData > &chanData, const gsl::span< const OrbitData > &pedData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:67
auto getBCShiftOrbits() const
Definition CTFCoder.h:52
GLuint entry
Definition glcorearb.h:5735
const GLdouble * v
Definition glcorearb.h:832
constexpr int LHCMaxBunches
struct o2::upgrades_utils::@463 zdc
structure to keep FT0 information
constexpr int NModules
Definition Constants.h:68
constexpr int NTimeBinsPerBC
Definition Constants.h:53
constexpr int NChannels
Definition Constants.h:65
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
Detector header base.
wrapper for the Entropy-encoded triggers and cells of the TF
Definition CTF.h:44
@ BLC_bcIncTrig
Definition CTF.h:47
@ BLC_sclInc
Definition CTF.h:60
@ BLC_moduleTrig
Definition CTF.h:49
@ BLC_orbitIncTrig
Definition CTF.h:48
@ BLC_channelsHL
Definition CTF.h:50
@ BLC_triggersHL
Definition CTF.h:51
@ BLC_chanData
Definition CTF.h:56
@ BLC_pedData
Definition CTF.h:59
@ BLC_extTriggers
Definition CTF.h:52
@ BLC_orbitIncEOD
Definition CTF.h:58
@ BLC_chanID
Definition CTF.h:55
@ BLC_nchanTrig
Definition CTF.h:53
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))