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_HMPID_CTFCODER_H
17#define O2_HMPID_CTFCODER_H
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include <array>
23#include "DataFormatsHMP/CTF.h"
27
28class TTree;
29
30namespace o2
31{
32namespace hmpid
33{
34
36{
37 public:
38 CTFCoder(o2::ctf::CTFCoderBase::OpType op) : o2::ctf::CTFCoderBase(op, CTF::getNBlocks(), o2::detectors::DetID::HMP) {}
39 ~CTFCoder() final = default;
40
42 template <typename VEC>
43 o2::ctf::CTFIOSize encode(VEC& buff, const gsl::span<const Trigger>& trigData, const gsl::span<const Digit>& digData);
44
46 template <typename VTRG, typename VDIG>
47 o2::ctf::CTFIOSize decode(const CTF::base& ec, VTRG& trigVec, VDIG& digVec);
48
49 void createCoders(const std::vector<char>& bufVec, o2::ctf::CTFCoderBase::OpType op) final;
50
51 private:
52 template <typename VEC>
53 o2::ctf::CTFIOSize encode_impl(VEC& buff, const gsl::span<const Trigger>& trigData, const gsl::span<const Digit>& digData);
54 void appendToTree(TTree& tree, CTF& ec);
55 void readFromTree(TTree& tree, int entry, std::vector<Trigger>& trigVec, std::vector<Digit>& digVec);
56 std::vector<Trigger> mTrgRecFilt;
57 std::vector<Digit> mDigDataFilt;
58};
59
61template <typename VEC>
62o2::ctf::CTFIOSize CTFCoder::encode(VEC& buff, const gsl::span<const Trigger>& trigData, const gsl::span<const Digit>& digData)
63{
64 if (mIRFrameSelector.isSet()) { // preselect data
65 mTrgRecFilt.clear();
66 mDigDataFilt.clear();
67 for (const auto& trig : trigData) {
68 if (mIRFrameSelector.check(trig.getIr()) >= 0) {
69 mTrgRecFilt.push_back(trig);
70 auto digIt = digData.begin() + trig.getFirstEntry();
71 auto& trigC = mTrgRecFilt.back();
72 trigC.setDataRange((int)mDigDataFilt.size(), trig.getNumberOfObjects());
73 std::copy(digIt, digIt + trig.getNumberOfObjects(), std::back_inserter(mDigDataFilt));
74 }
75 }
76 return encode_impl(buff, mTrgRecFilt, mDigDataFilt);
77 }
78 return encode_impl(buff, trigData, digData);
79}
80
81template <typename VEC>
82o2::ctf::CTFIOSize CTFCoder::encode_impl(VEC& buff, const gsl::span<const Trigger>& trigData, const gsl::span<const Digit>& digData)
83{
85 // what to do which each field: see o2::ctd::Metadata explanation
86 constexpr MD optField[CTF::getNBlocks()] = {
87 MD::EENCODE_OR_PACK, // BLC_bcIncTrig
88 MD::EENCODE_OR_PACK, // BLC_orbitIncTrig
89 MD::EENCODE_OR_PACK, // BLC_entriesDig
90 MD::EENCODE_OR_PACK, // BLC_ChID
91 MD::EENCODE_OR_PACK, // BLC_Q
92 MD::EENCODE_OR_PACK, // BLC_Ph
93 MD::EENCODE_OR_PACK, // BLC_X
94 MD::EENCODE_OR_PACK // BLC_Y
95 };
96
97 CTFHelper helper(trigData, digData);
98
99 // book output size with some margin
100 auto szIni = sizeof(CTFHeader) + helper.getSize() * 2. / 3; // will be autoexpanded if needed
101 buff.resize(szIni);
102
103 auto ec = CTF::create(buff);
104 using ECB = CTF::base;
105
106 ec->setHeader(helper.createHeader());
107 assignDictVersion(static_cast<o2::ctf::CTFDictHeader&>(ec->getHeader()));
108 ec->setANSHeader(mANSVersion);
109 // at every encoding the buffer might be autoexpanded, so we don't work with fixed pointer ec
110 o2::ctf::CTFIOSize iosize;
111#define ENCODEHMP(beg, end, slot, bits) CTF::get(buff.data())->encode(beg, end, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
112 // clang-format off
113 iosize += ENCODEHMP(helper.begin_bcIncTrig(), helper.end_bcIncTrig(), CTF::BLC_bcIncTrig, 0);
114 iosize += ENCODEHMP(helper.begin_orbitIncTrig(), helper.end_orbitIncTrig(), CTF::BLC_orbitIncTrig, 0);
115 iosize += ENCODEHMP(helper.begin_entriesDig(), helper.end_entriesDig(), CTF::BLC_entriesDig, 0);
116
117 iosize += ENCODEHMP(helper.begin_ChID(), helper.end_ChID(), CTF::BLC_ChID, 0);
118 iosize += ENCODEHMP(helper.begin_Q(), helper.end_Q(), CTF::BLC_Q, 0);
119 iosize += ENCODEHMP(helper.begin_Ph(), helper.end_Ph(), CTF::BLC_Ph, 0);
120 iosize += ENCODEHMP(helper.begin_X(), helper.end_X(), CTF::BLC_X, 0);
121 iosize += ENCODEHMP(helper.begin_Y(), helper.end_Y(), CTF::BLC_Y, 0);
122
123 // clang-format on
124 CTF::get(buff.data())->print(getPrefix(), mVerbosity);
125 finaliseCTFOutput<CTF>(buff);
126 iosize.rawIn = trigData.size() * sizeof(Trigger) + digData.size() * sizeof(Digit);
127 return iosize;
128}
129
131template <typename VTRG, typename VDIG>
132o2::ctf::CTFIOSize CTFCoder::decode(const CTF::base& ec, VTRG& trigVec, VDIG& digVec)
133{
134 auto header = ec.getHeader();
135 checkDictVersion(static_cast<const o2::ctf::CTFDictHeader&>(header));
137 std::vector<int16_t> bcInc;
138 std::vector<int32_t> orbitInc;
139 std::vector<uint16_t> q;
140 std::vector<uint32_t> entriesDig;
141 std::vector<uint8_t> chID, ph, x, y;
142
143 o2::ctf::CTFIOSize iosize;
144#define DECODEHMP(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
145 // clang-format off
146 iosize += DECODEHMP(bcInc, CTF::BLC_bcIncTrig);
147 iosize += DECODEHMP(orbitInc, CTF::BLC_orbitIncTrig);
148 iosize += DECODEHMP(entriesDig, CTF::BLC_entriesDig);
149
150 iosize += DECODEHMP(chID, CTF::BLC_ChID);
151 iosize += DECODEHMP(q, CTF::BLC_Q);
152 iosize += DECODEHMP(ph, CTF::BLC_Ph);
153 iosize += DECODEHMP(x, CTF::BLC_X);
154 iosize += DECODEHMP(y, CTF::BLC_Y);
155 // clang-format on
156 //
157 trigVec.clear();
158 digVec.clear();
159 trigVec.reserve(header.nTriggers);
160 digVec.reserve(header.nDigits);
161
162 uint32_t digCount = 0;
163 o2::InteractionRecord ir(header.firstBC, header.firstOrbit);
164 bool checkIROK = (mBCShift == 0); // need to check if CTP offset correction does not make the local time negative ?
165 for (uint32_t itrig = 0; itrig < header.nTriggers; itrig++) {
166 // restore TrigRecord
167 if (orbitInc[itrig]) { // non-0 increment => new orbit
168 ir.bc = bcInc[itrig]; // bcInc has absolute meaning
169 ir.orbit += orbitInc[itrig];
170 } else {
171 ir.bc += bcInc[itrig];
172 }
173
174 int8_t chid = 0;
175 if (checkIROK || canApplyBCShift(ir)) { // correction will be ok
176 checkIROK = true;
177 } else { // correction would make IR prior to mFirstTFOrbit, skip
178 digCount += entriesDig[itrig];
179 continue;
180 }
181 uint32_t firstEntryDig = digVec.size();
182 for (uint32_t id = 0; id < entriesDig[itrig]; id++) {
183 chid += chID[digCount]; // 1st digit of trigger was encoded with abs ChID, then increments
184 auto& dig = digVec.emplace_back(chid, ph[digCount], x[digCount], y[digCount], q[digCount]);
185 digCount++;
186 }
187
188 trigVec.emplace_back(ir - mBCShift, firstEntryDig, entriesDig[itrig]);
189 }
190 assert(digCount == header.nDigits);
191 iosize.rawIn = trigVec.size() * sizeof(Trigger) + digVec.size() * sizeof(Digit);
192 return iosize;
193}
194
195} // namespace hmpid
196} // namespace o2
197
198#endif // O2_HMP_CTFCODER_H
Declarations for CTFCoderBase class (support of external dictionaries)
uint32_t op
Definitions for HMPID CTF data.
#define ENCODEHMP(beg, end, slot, bits)
#define DECODEHMP(part, slot)
Helper for HMPID 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
~CTFCoder() final=default
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const Trigger > &trigData, const gsl::span< const Digit > &digData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:62
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
Definition CTFCoder.cxx:40
CTFCoder(o2::ctf::CTFCoderBase::OpType op)
Definition CTFCoder.h:38
o2::ctf::CTFIOSize decode(const CTF::base &ec, VTRG &trigVec, VDIG &digVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:132
HMPID Digit declaration.
Definition Digit.h:36
HMPID Trigger declaration.
Definition Trigger.h:32
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint entry
Definition glcorearb.h:5735
GLint y
Definition glcorearb.h:270
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:39
@ BLC_orbitIncTrig
Definition CTF.h:43
@ BLC_bcIncTrig
Definition CTF.h:42
@ BLC_entriesDig
Definition CTF.h:44
std::vector< o2::mch::DsChannelId > chid
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))