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_CTP_CTFCODER_H
17#define O2_CTP_CTFCODER_H
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include <array>
23#include "DataFormatsCTP/CTF.h"
29#include <vector>
30
31class TTree;
32
33namespace o2
34{
35namespace ctp
36{
37
39{
40 public:
41 CTFCoder(o2::ctf::CTFCoderBase::OpType op) : o2::ctf::CTFCoderBase(op, CTF::getNBlocks(), o2::detectors::DetID::CTP) {}
42 ~CTFCoder() final = default;
43
45 template <typename VEC>
46 o2::ctf::CTFIOSize encode(VEC& buff, const gsl::span<const CTPDigit>& data, const LumiInfo& lumi);
47
49 template <typename VTRG>
50 o2::ctf::CTFIOSize decode(const CTF::base& ec, VTRG& data, LumiInfo& lumi);
51
53 template <typename CTF>
54 bool finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj);
55
56 void createCoders(const std::vector<char>& bufVec, o2::ctf::CTFCoderBase::OpType op) final;
57 void setDecodeInps(bool decodeinps) { mDecodeInps = decodeinps; }
58 void setCTPConfig(CTPConfiguration cfg) { mCTPConfig = std::move(cfg); }
59 bool getDecodeInps() { return mDecodeInps; }
60 CTPConfiguration& getCTPConfig() { return mCTPConfig; }
61 bool canApplyBCShiftInputs(const o2::InteractionRecord& ir) const { return canApplyBCShift(ir, mBCShiftInputs); }
62
63 private:
64 template <typename VEC>
65 o2::ctf::CTFIOSize encode_impl(VEC& buff, const gsl::span<const CTPDigit>& data, const LumiInfo& lumi);
66
67 void appendToTree(TTree& tree, CTF& ec);
68 void readFromTree(TTree& tree, int entry, std::vector<CTPDigit>& data, LumiInfo& lumi);
69 std::vector<CTPDigit> mDataFilt;
70 CTPConfiguration mCTPConfig;
71 int mBCShiftInputs = 0;
72 bool mDecodeInps = false;
73};
74
76template <typename VEC>
77o2::ctf::CTFIOSize CTFCoder::encode(VEC& buff, const gsl::span<const CTPDigit>& data, const LumiInfo& lumi)
78{
79 if (mIRFrameSelector.isSet()) { // preselect data
80 mDataFilt.clear();
81 for (const auto& trig : data) {
82 if (mIRFrameSelector.check(trig.intRecord) >= 0) {
83 mDataFilt.push_back(trig);
84 }
85 }
86 return encode_impl(buff, mDataFilt, lumi);
87 }
88 return encode_impl(buff, data, lumi);
89}
90
91template <typename VEC>
92o2::ctf::CTFIOSize CTFCoder::encode_impl(VEC& buff, const gsl::span<const CTPDigit>& data, const LumiInfo& lumi)
93{
95 // what to do which each field: see o2::ctd::Metadata explanation
96 constexpr MD optField[CTF::getNBlocks()] = {
97 MD::EENCODE_OR_PACK, // BLC_bcIncTrig
98 MD::EENCODE_OR_PACK, // BLC_orbitIncTrig
99 MD::EENCODE_OR_PACK, // BLC_bytesInput
100 MD::EENCODE_OR_PACK, // BLC_bytesClass
101 };
102
103 CTFHelper helper(data);
104
105 // book output size with some margin
106 auto szIni = sizeof(CTFHeader) + helper.getSize() * 2. / 3; // will be autoexpanded if needed
107 buff.resize(szIni);
108
109 auto ec = CTF::create(buff);
110 using ECB = CTF::base;
111
112 ec->setHeader(helper.createHeader(lumi));
113 assignDictVersion(static_cast<o2::ctf::CTFDictHeader&>(ec->getHeader()));
114 ec->setANSHeader(mANSVersion);
115 // at every encoding the buffer might be autoexpanded, so we don't work with fixed pointer ec
116 o2::ctf::CTFIOSize iosize;
117#define ENCODECTP(beg, end, slot, bits) CTF::get(buff.data())->encode(beg, end, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
118 // clang-format off
119 iosize += ENCODECTP(helper.begin_bcIncTrig(), helper.end_bcIncTrig(), CTF::BLC_bcIncTrig, 0);
120 iosize += ENCODECTP(helper.begin_orbitIncTrig(), helper.end_orbitIncTrig(), CTF::BLC_orbitIncTrig, 0);
121 iosize += ENCODECTP(helper.begin_bytesInput(), helper.end_bytesInput(), CTF::BLC_bytesInput, 0);
122 iosize += ENCODECTP(helper.begin_bytesClass(), helper.end_bytesClass(), CTF::BLC_bytesClass, 0);
123 // clang-format on
124 CTF::get(buff.data())->print(getPrefix(), mVerbosity);
125 finaliseCTFOutput<CTF>(buff);
126 iosize.rawIn = data.size() * sizeof(CTPDigit);
127 return iosize;
128}
129
131template <typename VTRG>
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<uint8_t> bytesInput, bytesClass;
140
141 o2::ctf::CTFIOSize iosize;
142#define DECODECTP(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
143 // clang-format off
144 iosize += DECODECTP(bcInc, CTF::BLC_bcIncTrig);
145 iosize += DECODECTP(orbitInc, CTF::BLC_orbitIncTrig);
146 iosize += DECODECTP(bytesInput, CTF::BLC_bytesInput);
147 iosize += DECODECTP(bytesClass, CTF::BLC_bytesClass);
148 // clang-format on
149 //
150 data.clear();
151 std::map<o2::InteractionRecord, CTPDigit> digitsMap;
152 o2::InteractionRecord ir(header.firstBC, header.firstOrbit);
153 lumi.nHBFCounted = header.lumiNHBFs;
154 lumi.nHBFCountedFV0 = header.lumiNHBFsFV0 ? header.lumiNHBFsFV0 : header.lumiNHBFs;
155 lumi.counts = header.lumiCounts;
156 lumi.countsFV0 = header.lumiCountsFV0;
157 lumi.orbit = header.lumiOrbit;
158 lumi.inp1 = int(header.inp1);
159 lumi.inp2 = int(header.inp2);
160 auto itInp = bytesInput.begin();
161 auto itCls = bytesClass.begin();
162 bool checkIROK = (mBCShift == 0); // need to check if CTP offset correction does not make the local time negative ?
163 bool checkIROKInputs = (mBCShiftInputs == 0); // need to check if CTP offset correction does not make the local time negative ?
164 for (uint32_t itrig = 0; itrig < header.nTriggers; itrig++) {
165 // restore TrigRecord
166 if (orbitInc[itrig]) { // non-0 increment => new orbit
167 ir.bc = bcInc[itrig]; // bcInc has absolute meaning
168 ir.orbit += orbitInc[itrig];
169 } else {
170 ir.bc += bcInc[itrig];
171 }
172 if (checkIROKInputs || canApplyBCShiftInputs(ir)) { // correction will be ok
173 auto irs = ir - mBCShiftInputs;
174 uint64_t CTPInputMask = 0;
175 for (int i = 0; i < CTFHelper::CTPInpNBytes; i++) {
176 CTPInputMask |= static_cast<uint64_t>(*itInp++) << (8 * i);
177 }
178 if (CTPInputMask) {
179 if (digitsMap.count(irs)) {
180 if (digitsMap[irs].isInputEmpty()) {
181 digitsMap[irs].CTPInputMask = CTPInputMask;
182 // LOG(info) << "IR1:";
183 // digitsMap[irs].printStream(std::cout);
184 } else {
185 LOG(error) << "CTPInpurMask already exist:" << irs << " dig.CTPInputMask:" << digitsMap[irs].CTPInputMask << " CTPInputMask:" << CTPInputMask;
186 }
187 } else {
188 CTPDigit dig = {irs, CTPInputMask, 0};
189 digitsMap[irs] = dig;
190 // LOG(info) << "IR2:";
191 // digitsMap[irs].printStream(std::cout);
192 }
193 }
194 } else { // correction would make IR prior to mFirstTFOrbit, skip
196 }
197 if (checkIROK || canApplyBCShift(ir)) { // correction will be ok
198 auto irs = ir - mBCShift;
199 uint64_t CTPClassMask = 0;
200 for (int i = 0; i < CTFHelper::CTPClsNBytes; i++) {
201 CTPClassMask |= static_cast<uint64_t>(*itCls++) << (8 * i);
202 }
203 if (CTPClassMask) {
204 if (digitsMap.count(irs)) {
205 if (digitsMap[irs].isClassEmpty()) {
206 digitsMap[irs].CTPClassMask = CTPClassMask;
207 // LOG(info) << "TCM1:";
208 // digitsMap[irs].printStream(std::cout);
209 } else {
210 LOG(error) << "CTPClassMask already exist:" << irs << " dig.CTPClassMask:" << digitsMap[irs].CTPClassMask << " CTPClassMask:" << CTPClassMask;
211 }
212 } else {
213 CTPDigit dig = {irs, 0, CTPClassMask};
214 digitsMap[irs] = dig;
215 // LOG(info) << "TCM2:";
216 // digitsMap[irs].printStream(std::cout);
217 }
218 }
219 } else { // correction would make IR prior to mFirstTFOrbit, skip
221 }
222 }
223 if (mDecodeInps) {
224 uint64_t trgclassmask = 0xffffffffffffffff;
225 if (mCTPConfig.getRunNumber() != 0) {
226 trgclassmask = mCTPConfig.getTriggerClassMask();
227 }
228 // std::cout << "trgclassmask:" << std::hex << trgclassmask << std::dec << std::endl;
229 std::pmr::vector<CTPDigit> digits;
231 for (auto const& dig : digits) {
232 data.emplace_back(dig);
233 }
234 } else {
235 for (auto const& dig : digitsMap) {
236 data.emplace_back(dig.second);
237 }
238 }
239 assert(itInp == bytesInput.end());
240 assert(itCls == bytesClass.end());
241 iosize.rawIn = header.nTriggers * sizeof(CTPDigit);
242 return iosize;
243}
245template <typename CTF = o2::ctp::CTF>
247{
248 auto match = o2::ctf::CTFCoderBase::finaliseCCDB<CTF>(matcher, obj);
249 mBCShiftInputs = -o2::ctp::TriggerOffsetsParam::Instance().globalInputsShift;
250 LOG(info) << "BCShiftInputs:" << mBCShiftInputs;
251 return match;
252}
253
254} // namespace ctp
255} // namespace o2
256
257#endif // O2_CTP_CTFCODER_H
Declarations for CTFCoderBase class (support of external dictionaries)
Definitions for CTP CTF data.
#define ENCODECTP(beg, end, slot, bits)
#define DECODECTP(part, slot)
Helper for CTP CTF creation.
definition of CTPConfiguration and related CTP structures
int32_t i
uint32_t op
Digits tw Raw translation.
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 ...
CTPConfiguration & getCTPConfig()
Definition CTFCoder.h:60
~CTFCoder() final=default
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const CTPDigit > &data, const LumiInfo &lumi)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:77
void setCTPConfig(CTPConfiguration cfg)
Definition CTFCoder.h:58
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
Definition CTFCoder.cxx:39
bool canApplyBCShiftInputs(const o2::InteractionRecord &ir) const
Definition CTFCoder.h:61
CTFCoder(o2::ctf::CTFCoderBase::OpType op)
Definition CTFCoder.h:41
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
add CTP related shifts
Definition CTFCoder.h:246
void setDecodeInps(bool decodeinps)
Definition CTFCoder.h:57
bool getDecodeInps()
Definition CTFCoder.h:59
o2::ctf::CTFIOSize decode(const CTF::base &ec, VTRG &data, LumiInfo &lumi)
entropy decode data from buffer with CTF
Definition CTFCoder.h:132
static constexpr int CTPClsNBytes
Definition CTFHelper.h:36
static constexpr int CTPInpNBytes
Definition CTFHelper.h:35
uint64_t getTriggerClassMask() const
static int shiftInputs(std::map< o2::InteractionRecord, CTPDigit > &digitsMap, std::pmr::vector< CTPDigit > &digits, uint32_t TFOrbit, uint64_t trgclassmask=0xffffffffffffffff)
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)
bool match(const std::vector< std::string > &queries, const char *pattern)
Definition dcs-ccdb.cxx:229
GLuint entry
Definition glcorearb.h:5735
GLboolean * data
Definition glcorearb.h:298
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 trigger inputs and classes of the TF
Definition CTF.h:45
@ BLC_bytesInput
Definition CTF.h:50
@ BLC_bytesClass
Definition CTF.h:51
@ BLC_bcIncTrig
Definition CTF.h:48
@ BLC_orbitIncTrig
Definition CTF.h:49
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()))
LumiInfo lumi
std::vector< Digit > digits