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