16#ifndef O2_FT0_CTFCODER_H
17#define O2_FT0_CTFCODER_H
44 template <typename VEC>
48 template <typename VDIG, typename VCHAN>
49 o2::ctf::CTFIOSize
decode(const
CTF::base& ec, VDIG& digitVec, VCHAN& channelVec);
55 template <
int MAJOR_VERSION,
int MINOR_VERSION>
60 template <
int MAJOR_VERSION,
int MINOR_VERSION, typename VDIG, typename VCHAN>
61 void decompress(const
CompressedDigits& cd, VDIG& digitVec, VCHAN& channelVec);
63 void appendToTree(TTree&
tree,
CTF& ec);
65 void assignDictVersion(
o2::ctf::CTFDictHeader&
h) const final;
69template <typename VEC>
88 compress<1, 0>(cd, digitVec, channelVec);
90 compress<1, 1>(cd, digitVec, channelVec);
93 compress<1, 1>(cd, digitVec, channelVec);
96 auto szIni = estimateCompressedSize(cd);
102 ec->setHeader(cd.header);
107#define ENCODEFT0(part, slot, bits) CTF::get(buff.data())->encode(part, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
120 finaliseCTFOutput<CTF>(buff);
126template <
typename VDIG,
typename VCHAN>
135#define DECODEFT0(part, slot) ec.decode(part, int(slot), mCoders[int(slot)])
148 if (hd.minorVersion == 0 && hd.majorVersion == 1) {
149 decompress<1, 0>(cd, digitVec, channelVec);
151 decompress<1, 1>(cd, digitVec, channelVec);
158template <
int MAJOR_VERSION,
int MINOR_VERSION,
typename VDIG,
typename VCHAN>
159void CTFCoder::decompress(
const CompressedDigits& cd, VDIG& digitVec, VCHAN& channelVec)
164 channelVec.reserve(cd.
idChan.size());
166 uint32_t firstEntry = 0, clCount = 0, chipCount = 0;
180 int triggerGate =
params.mTime_trg_gate;
181 firstEntry = channelVec.size();
186 for (uint8_t ic = 0; ic < cd.
nChan[idig]; ic++) {
187 auto icc = channelVec.size();
188 if constexpr (MINOR_VERSION == 0 && MAJOR_VERSION == 1) {
196 if (std::abs(chan.CFDTime) < triggerGate) {
198 amplA += chan.QTCAmpl;
199 timeA += chan.CFDTime;
202 amplC += chan.QTCAmpl;
203 timeC += chan.CFDTime;
224 auto& d = digitVec.emplace_back(firstEntry, cd.
nChan[idig],
ir, trig, idig);
230template <
int MAJOR_VERSION,
int MINOR_VERSION>
231void CTFCoder::compress(CompressedDigits& cd,
const gsl::span<const Digit>& digitVec,
const gsl::span<const ChannelData>& channelVec)
235 cd.header.det =
mDet;
236 if (!digitVec.size()) {
239 uint32_t firstDig = digitVec.size(), nDigSel = digitVec.size(), nChanSel = channelVec.size();
240 std::vector<bool> reject(digitVec.size());
242 for (
size_t id = 0;
id < digitVec.size();
id++) {
246 nChanSel -= digitVec[
id].ref.getEntries();
247 }
else if (firstDig == digitVec.size()) {
258 const auto& dig0 = digitVec[firstDig];
259 cd.header.nTriggers = nDigSel;
260 cd.header.firstOrbit = dig0.getOrbit();
261 cd.header.firstBC = dig0.getBC();
264 cd.trigger.resize(cd.header.nTriggers);
265 cd.bcInc.resize(cd.header.nTriggers);
266 cd.orbitInc.resize(cd.header.nTriggers);
267 cd.eventStatus.resize(cd.header.nTriggers);
268 cd.nChan.resize(cd.header.nTriggers);
270 cd.idChan.resize(nChanSel);
271 cd.qtcChain.resize(nChanSel);
272 cd.cfdTime.resize(nChanSel);
273 cd.qtcAmpl.resize(nChanSel);
275 uint16_t prevBC = cd.header.firstBC;
276 uint32_t prevOrbit = cd.header.firstOrbit;
277 uint32_t ccount = 0, dcount = 0;
278 for (uint32_t idig = 0; idig < digitVec.size(); idig++) {
282 const auto& digit = digitVec[idig];
283 const auto chanels = digit.getBunchChannelData(channelVec);
286 cd.trigger[dcount] = digit.getTriggers().getTriggersignals();
287 cd.eventStatus[dcount] = digit.getEventStatusWord();
288 if (prevOrbit == digit.getOrbit()) {
289 cd.bcInc[dcount] = digit.getBC() - prevBC;
290 cd.orbitInc[dcount] = 0;
292 cd.bcInc[dcount] = digit.getBC();
293 cd.orbitInc[dcount] = digit.getOrbit() - prevOrbit;
295 prevBC = digit.getBC();
296 prevOrbit = digit.getOrbit();
298 cd.nChan[dcount] = chanels.size();
299 if (!cd.nChan[dcount]) {
300 LOG(
debug) <<
"Digits with no channels";
305 for (uint8_t ic = 0; ic < cd.nChan[dcount]; ic++) {
306 if constexpr (MINOR_VERSION == 0 && MAJOR_VERSION == 1) {
307 cd.idChan[ccount] = chanels[ic].ChId - prevChan;
309 cd.idChan[ccount] = chanels[ic].ChId;
311 cd.qtcChain[ccount] = chanels[ic].ChainQTC;
312 cd.cfdTime[ccount] = chanels[ic].CFDTime;
313 cd.qtcAmpl[ccount] = chanels[ic].QTCAmpl;
314 prevChan = chanels[ic].ChId;
Declarations for CTFCoderBase class (support of external dictionaries)
#define ENCODEFT0(part, slot, bits)
#define DECODEFT0(part, slot)
Configurable digitization parameters.
Class for time synchronization of RawReader instances.
static const FT0DigParam & Instance()
void checkDictVersion(const CTFDictHeader &h) const
ctf::ANSHeader mANSVersion
std::string getPrefix() const
o2::utils::IRFrameSelector mIRFrameSelector
<<======================== 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
static constexpr int getNBlocks()
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.
static const int16_t DEFAULT_AMP
static const int16_t DEFAULT_TIME
void setTriggers(uint8_t trgsig, uint8_t chanA, uint8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const Digit > &digitVec, const gsl::span< const ChannelData > &channelVec)
entropy-encode digits to buffer with CTF
o2::ctf::CTFIOSize decode(const CTF::base &ec, VDIG &digitVec, VCHAN &channelVec)
entropy decode clusters from buffer with CTF
CTFCoder(o2::ctf::CTFCoderBase::OpType op, const std::string &ctfdictOpt="none")
~CTFCoder() final=default
static constexpr int NCellsA
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
GLenum const GLfloat * params
uint8_t itsSharedClusterMap uint8_t
o2::fit::Triggers Triggers
struct o2::upgrades_utils::@477 ft0
structure to keep V0C information
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint16_t bc
bunch crossing ID of interaction
wrapper for the Entropy-encoded clusters of the TF
Intermediate, compressed but not yet entropy-encoded digits.
std::vector< uint8_t > trigger
std::vector< uint8_t > idChan
std::vector< uint8_t > eventStatus
std::vector< int16_t > bcInc
std::vector< uint8_t > nChan
std::vector< int32_t > orbitInc
std::vector< int32_t > qtcAmpl
std::vector< int16_t > cfdTime
std::vector< uint8_t > qtcChain
std::vector< o2::mch::ChannelCode > cc
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()))