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_PHOS_CTFCODER_H
17#define O2_PHOS_CTFCODER_H
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include <array>
23#include "DataFormatsPHOS/CTF.h"
27
28class TTree;
29
30namespace o2
31{
32namespace phos
33{
34
36{
37 public:
38 CTFCoder(o2::ctf::CTFCoderBase::OpType op) : o2::ctf::CTFCoderBase(op, CTF::getNBlocks(), o2::detectors::DetID::PHS) {}
39 ~CTFCoder() final = default;
40
42 template <typename VEC>
43 o2::ctf::CTFIOSize encode(VEC& buff, const gsl::span<const TriggerRecord>& trigData, const gsl::span<const Cell>& cellData);
44
46 template <typename VTRG, typename VCELL>
47 o2::ctf::CTFIOSize decode(const CTF::base& ec, VTRG& trigVec, VCELL& cellVec);
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 TriggerRecord>& trigData, const gsl::span<const Cell>& cellData);
54 void appendToTree(TTree& tree, CTF& ec);
55 void readFromTree(TTree& tree, int entry, std::vector<TriggerRecord>& trigVec, std::vector<Cell>& cellVec);
56 std::vector<TriggerRecord> mTrgDataFilt;
57 std::vector<Cell> mCellDataFilt;
58};
59
61template <typename VEC>
62o2::ctf::CTFIOSize CTFCoder::encode(VEC& buff, const gsl::span<const TriggerRecord>& trigData, const gsl::span<const Cell>& cellData)
63{
64 if (mIRFrameSelector.isSet()) { // preselect data
65 mTrgDataFilt.clear();
66 mCellDataFilt.clear();
67 for (const auto& trig : trigData) {
68 if (mIRFrameSelector.check(trig.getBCData()) >= 0) {
69 mTrgDataFilt.push_back(trig);
70 auto cellIt = cellData.begin() + trig.getFirstEntry();
71 auto& trigC = mTrgDataFilt.back();
72 trigC.setDataRange((int)mCellDataFilt.size(), trig.getNumberOfObjects());
73 std::copy(cellIt, cellIt + trig.getNumberOfObjects(), std::back_inserter(mCellDataFilt));
74 }
75 }
76 return encode_impl(buff, mTrgDataFilt, mCellDataFilt);
77 }
78 return encode_impl(buff, trigData, cellData);
79}
80
81template <typename VEC>
82o2::ctf::CTFIOSize CTFCoder::encode_impl(VEC& buff, const gsl::span<const TriggerRecord>& trigData, const gsl::span<const Cell>& cellData)
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_entriesTrig
90 MD::EENCODE_OR_PACK, // BLC_packedID
91 MD::EENCODE_OR_PACK, // BLC_time
92 MD::EENCODE_OR_PACK, // BLC_energy
93 MD::EENCODE_OR_PACK // BLC_status
94 };
95
96 CTFHelper helper(trigData, cellData);
97
98 // book output size with some margin
99 auto szIni = sizeof(CTFHeader) + helper.getSize() * 2. / 3; // will be autoexpanded if needed
100 buff.resize(szIni);
101
102 auto ec = CTF::create(buff);
103 using ECB = CTF::base;
104
105 ec->setHeader(helper.createHeader());
106 assignDictVersion(static_cast<o2::ctf::CTFDictHeader&>(ec->getHeader()));
107 ec->setANSHeader(mANSVersion);
108 // at every encoding the buffer might be autoexpanded, so we don't work with fixed pointer ec
109 o2::ctf::CTFIOSize iosize;
110#define ENCODEPHS(beg, end, slot, bits) CTF::get(buff.data())->encode(beg, end, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
111 // clang-format off
112 iosize += ENCODEPHS(helper.begin_bcIncTrig(), helper.end_bcIncTrig(), CTF::BLC_bcIncTrig, 0);
113 iosize += ENCODEPHS(helper.begin_orbitIncTrig(), helper.end_orbitIncTrig(), CTF::BLC_orbitIncTrig, 0);
114 iosize += ENCODEPHS(helper.begin_entriesTrig(), helper.end_entriesTrig(), CTF::BLC_entriesTrig, 0);
115
116 iosize += ENCODEPHS(helper.begin_packedID(), helper.end_packedID(), CTF::BLC_packedID, 0);
117 iosize += ENCODEPHS(helper.begin_time(), helper.end_time(), CTF::BLC_time, 0);
118 iosize += ENCODEPHS(helper.begin_energy(), helper.end_energy(), CTF::BLC_energy, 0);
119 iosize += ENCODEPHS(helper.begin_status(), helper.end_status(), CTF::BLC_status, 0);
120 // clang-format on
121 CTF::get(buff.data())->print(getPrefix(), mVerbosity);
122 finaliseCTFOutput<CTF>(buff);
123 iosize.rawIn = trigData.size() * sizeof(TriggerRecord) + cellData.size() * sizeof(Cell);
124 return iosize;
125}
126
128template <typename VTRG, typename VCELL>
129o2::ctf::CTFIOSize CTFCoder::decode(const CTF::base& ec, VTRG& trigVec, VCELL& cellVec)
130{
131 const auto& header = ec.getHeader();
132 checkDictVersion(static_cast<const o2::ctf::CTFDictHeader&>(header));
134 std::vector<int16_t> bcInc;
135 std::vector<int32_t> orbitInc;
136 std::vector<uint16_t> entries, energy, cellTime, packedID;
137 std::vector<uint8_t> status;
138
139 o2::ctf::CTFIOSize iosize;
140#define DECODEPHOS(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
141 // clang-format off
142 iosize += DECODEPHOS(bcInc, CTF::BLC_bcIncTrig);
143 iosize += DECODEPHOS(orbitInc, CTF::BLC_orbitIncTrig);
144 iosize += DECODEPHOS(entries, CTF::BLC_entriesTrig);
145 iosize += DECODEPHOS(packedID, CTF::BLC_packedID);
146
147 iosize += DECODEPHOS(cellTime, CTF::BLC_time);
148 iosize += DECODEPHOS(energy, CTF::BLC_energy);
149 iosize += DECODEPHOS(status, CTF::BLC_status);
150 // clang-format on
151 //
152 trigVec.clear();
153 cellVec.clear();
154 trigVec.reserve(header.nTriggers);
155 status.reserve(header.nCells);
156
157 uint32_t firstEntry = 0, cellCount = 0;
158 o2::InteractionRecord ir(header.firstBC, header.firstOrbit);
159 int64_t diffIR0 = 0;
160 bool checkIROK = (mBCShift == 0); // need to check if CTP offset correction does not make the local time negative ?
161 Cell cell;
162 for (uint32_t itrig = 0; itrig < header.nTriggers; itrig++) {
163 // restore TrigRecord
164 if (orbitInc[itrig]) { // non-0 increment => new orbit
165 ir.bc = bcInc[itrig]; // bcInc has absolute meaning
166 ir.orbit += orbitInc[itrig];
167 } else {
168 ir.bc += bcInc[itrig];
169 }
170 firstEntry = cellVec.size();
171 if (checkIROK || canApplyBCShift(ir)) { // correction will be ok
172 checkIROK = true;
173 } else { // correction would make IR prior to mFirstTFOrbit, skip
174 cellCount += entries[itrig];
175 continue;
176 }
177 for (uint16_t ic = 0; ic < entries[itrig]; ic++) {
178 cell.setPacked(packedID[cellCount], cellTime[cellCount], energy[cellCount], status[cellCount]);
179 cellVec.emplace_back(cell);
180 cellCount++;
181 }
182 trigVec.emplace_back(ir - mBCShift, firstEntry, entries[itrig]);
183 }
184 assert(cellCount == header.nCells);
185 iosize.rawIn = trigVec.size() * sizeof(TriggerRecord) + cellVec.size() * sizeof(Cell);
186 return iosize;
187}
188
189} // namespace phos
190} // namespace o2
191
192#endif // O2_PHOS_CTFCODER_H
Declarations for CTFCoderBase class (support of external dictionaries)
uint32_t op
Definitions for PHOS CTF data.
#define DECODEPHOS(part, slot)
#define ENCODEPHS(beg, end, slot, bits)
Helper for PHOS 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
o2::ctf::CTFIOSize decode(const CTF::base &ec, VTRG &trigVec, VCELL &cellVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:129
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
Definition CTFCoder.cxx:40
~CTFCoder() final=default
CTFCoder(o2::ctf::CTFCoderBase::OpType op)
Definition CTFCoder.h:38
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const TriggerRecord > &trigData, const gsl::span< const Cell > &cellData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:62
void setPacked(uint16_t id, uint16_t t, uint16_t en, uint16_t status)
Definition Cell.h:109
Header for data corresponding to the same hardware trigger adapted from DataFormatsEMCAL/TriggerRecor...
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
GLuint entry
Definition glcorearb.h:5735
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:41
@ BLC_energy
Definition CTF.h:49
@ BLC_orbitIncTrig
Definition CTF.h:45
@ BLC_packedID
Definition CTF.h:47
@ BLC_bcIncTrig
Definition CTF.h:44
@ BLC_status
Definition CTF.h:50
@ BLC_time
Definition CTF.h:48
@ BLC_entriesTrig
Definition CTF.h:46
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))