16#ifndef O2_ITSMFT_CTFCODER_H
17#define O2_ITSMFT_CTFCODER_H
56 template <typename VEC>
61 template <typename VROF, typename VCLUS, typename VPAT>
65 template <typename VROF, typename VDIG>
79 template <typename VROF, typename VCLUS, typename VPAT>
83 template <typename VROF, typename VDIG>
86 void appendToTree(TTree&
tree,
CTF& ec,
int id = -1);
89 bool mDoStaggering{
false};
94template <
typename VEC>
100 int strobeLength = mDoStaggering ? par.roFrameLayerLengthInBC[
layer] : par.roFrameLengthInBC;
119 auto szIni = estimateCompressedSize(compCl);
125 ec->setHeader(compCl.
header);
127 ec->setANSHeader(mANSVersion);
130#define ENCODEITSMFT(part, slot, bits) CTF::get(buff.data())->encode(part, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
151template <
typename VROF,
typename VCLUS,
typename VPAT>
155 auto compCl = decodeCompressedClusters(ec, iosize);
157 uint32_t nLayers = mDoStaggering ? par.getNLayers() : 1;
158 if (compCl.header.maxStreams != nLayers) {
159 throw std::runtime_error(fmt::format(
"header maxStreams={} is not the same as NStreams={} in {}staggered mode", compCl.header.maxStreams, nLayers, mDoStaggering ?
"" :
"non-"));
168template <
typename VROF,
typename VDIG>
172 auto compCl = decodeCompressedClusters(ec, iosize);
173 decompress(compCl, rofRecVec, digVec, noiseMap,
clPattLookup);
180template <
typename VROF,
typename VCLUS,
typename VPAT>
184 RowColBuff firedPixBuff{}, maskedPixBuff{};
191 uint32_t clCount = 0, chipCount = 0;
192 auto pattIt = compCl.
pattMap.begin();
193 auto pattItStored = pattIt;
198 auto clusterize = [&](uint16_t chipID, int16_t
row, int16_t
col,
int leftFired) {
199#ifdef _ALLOW_DIAGONAL_ALPIDE_CLUSTERS_
200 const std::array<int16_t, 8> walkRow = {1, -1, 0, 0, 1, 1, -1, -1};
201 const std::array<int16_t, 8> walkCol = {0, 0, -1, 1, 1, -1, 1, 1};
203 const std::array<int16_t, 4> walkRow = {1, -1, 0, 0};
204 const std::array<int16_t, 4> walkCol = {0, 0, -1, 1};
206 Clusterer::BBox
bbox(chipID);
208 std::function<
bool(int16_t, int16_t)> checkPixelAndNeighbours = [&](int16_t ir1, int16_t ic1) {
210 auto checkPixel = [&](int16_t ir1, int16_t ic1) {
211 if (pmat[ir1][ic1]) {
212 pmat[ir1][ic1] =
false;
213 uint16_t
r =
row + ir1 - 1,
c =
col + ic1 - 1;
214 firedPixBuff.emplace_back(
r,
c);
222 if (checkPixel(ir1, ic1) && leftFired) {
224 while (checkPixelAndNeighbours(ir1 + walkRow[iw], ic1 + walkCol[iw]) && ++iw < walkRow.size()) {
231 firedPixBuff.clear();
232 for (
auto s : maskedPixBuff) {
235 checkPixelAndNeighbours(
s.getRowDirect() + walkRow[iw],
s.getCol() + walkCol[iw]);
236 if (!firedPixBuff.empty()) {
237 bbox.chipID = chipID;
239 firedPixBuff.clear();
242 }
while (leftFired && ++iw < walkRow.size());
249 auto reclusterize = [&]() {
253 auto pattItPrev = pattIt;
254 maskedPixBuff.clear();
255 int rowRef = clus.getRow(), colRef = clus.getCol();
257 throw std::runtime_error(
"Clusters contain pattern IDs, but no dictionary is provided...");
263 float xCOG = 0, zCOG = 0;
265 rowRef -= round(xCOG);
266 colRef -= round(zCOG);
271 if (rowSpan == 1 && colSpan == 1) {
272 if (noiseMap->
isNoisy(clus.getChipID(), rowRef, colRef)) {
273 std::copy(pattItStored, pattItPrev, back_inserter(
pattVec));
274 pattItStored = pattIt;
280 for (
int ir = 0;
ir < rowSpan;
ir++) {
281 int row = rowRef +
ir;
282 for (
int ic = 0; ic < colSpan; ic++) {
284 if (noiseMap->
isNoisy(clus.getChipID(),
row, colRef + ic)) {
285 maskedPixBuff.emplace_back(
ir + 1, ic + 1);
286 pmat[
ir + 1][ic + 1] =
false;
289 pmat[
ir + 1][ic + 1] =
true;
293 pmat[
ir + 1][ic + 1] =
false;
300 std::copy(pattItStored, pattItPrev, back_inserter(
pattVec));
301 pattItStored = pattIt;
303 clusterize(clus.getChipID(), rowRef, colRef, nPixels);
310 for (uint32_t irof = 0; irof < compCl.
header.
nROFs; irof++) {
312 auto& rofRec = rofRecVec[irof];
319 rofRec.setBCData(prevIR);
320 rofRec.setFirstEntry(
cclusVec.size());
326 for (uint32_t icl = 0; icl < compCl.
nclusROF[irof]; icl++) {
327 auto& clus =
cclusVec.emplace_back();
328 if (inChip++ < compCl.
chipMul[chipCount]) {
329 clus.setCol((
col += compCl.
colInc[clCount]));
331 chipID += compCl.
chipInc[++chipCount];
333 clus.setCol((
col = compCl.
colInc[clCount]));
335 clus.setRow(compCl.
row[clCount]);
336 clus.setPatternID(compCl.
pattID[clCount]);
337 clus.setChipID(chipID);
346 rofRec.setNEntries(
cclusVec.size() - rofRec.getFirstEntry());
349 if (pattItStored != pattIt) {
350 std::copy(pattItStored, pattIt, back_inserter(
pattVec));
359 LOG(error) <<
"expected " << compCl.
header.
nClusters <<
" but counted " << clCount <<
" in ROFRecords";
360 throw std::runtime_error(
"mismatch between expected and counter number of clusters");
366template <
typename VROF,
typename VDIG>
367void CTFCoder<N>::decompress(
const CompressedClusters& compCl, VROF& rofRecVec, VDIG& digVec,
const NoiseMap* noiseMap,
const LookUp&
clPattLookup)
369 rofRecVec.resize(compCl.header.nROFs);
370 digVec.reserve(compCl.header.nClusters * 2);
372 uint32_t clCount = 0, chipCount = 0;
373 auto pattIt = compCl.pattMap.begin();
375 for (uint32_t irof = 0; irof < compCl.header.nROFs; irof++) {
376 size_t chipStartNDig = digVec.size();
378 auto& rofRec = rofRecVec[irof];
379 if (compCl.orbitIncROF[irof]) {
380 prevIR.bc = compCl.bcIncROF[irof];
381 prevIR.orbit += compCl.orbitIncROF[irof];
383 prevIR.bc += compCl.bcIncROF[irof];
385 rofRec.setBCData(prevIR);
386 rofRec.setFirstEntry(digVec.size());
389 uint16_t chipID = compCl.firstChipROF[irof],
col = 0;
391 for (uint32_t icl = 0; icl < compCl.nclusROF[irof]; icl++) {
392 if (inChip++ < compCl.chipMul[chipCount]) {
393 col += compCl.colInc[clCount];
396 auto added = digVec.size() - chipStartNDig;
398 std::sort(digVec.end() - added, digVec.end(),
399 [](Digit&
a, Digit&
b) { return a.getColumn() < b.getColumn() || (a.getColumn() == b.getColumn() && a.getRow() < b.getRow()); });
401 chipStartNDig = digVec.size();
402 chipID += compCl.chipInc[++chipCount];
403#ifdef _CHECK_INCREMENTES_
404 if (int16_t(compCl.chipInc[chipCount]) < 0) {
405 LOG(warning) <<
"Negative chip increment " << int16_t(compCl.chipInc[chipCount]) <<
" -> " << chipID;
409 col = compCl.colInc[clCount];
411 uint16_t rowRef = compCl.row[clCount], colRef =
col;
412 auto pattID = compCl.pattID[clCount];
417 throw std::runtime_error(
"Clusters contain pattern IDs, but no dictionary is provided...");
423 float xCOG = 0., zCOG = 0.;
425 rowRef -= round(xCOG);
426 colRef -= round(zCOG);
433 auto fillRowCol = [&digVec, chipID, rowRef, colRef, noiseMap](
int r,
int c) {
436 if (noiseMap && noiseMap->isNoisy(chipID,
r,
c)) {
439 digVec.emplace_back(chipID, uint16_t(
r), uint16_t(
c));
443 auto added = digVec.size() - chipStartNDig;
445 std::sort(digVec.end() - added, digVec.end(),
446 [](Digit&
a, Digit&
b) { return a.getColumn() < b.getColumn() || (a.getColumn() == b.getColumn() && a.getRow() < b.getRow()); });
449 if (compCl.nclusROF[irof]) {
452 rofRec.setNEntries(digVec.size() - rofRec.getFirstEntry());
455 assert(pattIt == compCl.pattMap.end());
456 assert(chipCount == compCl.header.nChips);
458 if (clCount != compCl.header.nClusters) {
459 LOG(error) <<
"expected " << compCl.header.nClusters <<
" but counted " << clCount <<
" in ROFRecords";
460 throw std::runtime_error(
"mismatch between expected and counter number of clusters");
Declarations for CTFCoderBase class (support of external dictionaries)
Definition of the ITSMFT compact cluster.
#define ENCODEITSMFT(part, slot, bits)
Definition of the ITS cluster finder.
Definition of the LookUp class.
Definition of the ITSMFT NoiseMap.
Transient data classes for single pixel and set of pixels from current chip.
static const DPLAlpideParam< N > & Instance()
<<======================== Auxiliary classes =======================<<
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.
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
~CTFCoder() final=default
static constexpr o2::detectors::DetID ID
std::array< std::array< bool, ClusterPattern::MaxRowSpan+2 >, ClusterPattern::MaxColSpan+2 > PMatrix
CTFCoder(o2::ctf::CTFCoderBase::OpType op, bool doStag, const std::string &ctfdictOpt="none")
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const ROFRecord > &rofRecVec, const gsl::span< const CompClusterExt > &cclusVec, const gsl::span< const unsigned char > &pattVec, const LookUp &clPattLookup, int layer)
entropy-encode clusters to buffer with CTF
std::vector< PixelData > RowColBuff
o2::ctf::CTFIOSize decode(const CTF::base &ec, VROF &rofRecVec, VCLUS &cclusVec, VPAT &pattVec, const NoiseMap *noiseMap, const LookUp &clPattLookup)
entropy decode clusters from buffer with CTF
int getRowSpan() const
Returns the number of rows.
void acquirePattern(iterator &pattIt)
int getColumnSpan() const
Returns the number of columns.
static int getCOG(int rowSpan, int colSpan, const unsigned char patt[MaxPatternBytes], float &xCOG, float &zCOG)
Static: Compute pattern's COG position. Returns the number of fired pixels.
void process(Processor procRowCol)
bool isSet(int row, int col) const
static constexpr uint8_t MaxColSpan
static void streamCluster(const std::vector< PixelData > &pixbuf, const std::array< Label, MaxLabels > *lblBuff, const BBox &bbox, const LookUp &pattIdConverter, VCLUS *compClusPtr, VPAT *patternsPtr, MCTruth *labelsClusPtr, int nlab, bool isHuge=false)
static constexpr unsigned short InvalidPatternID
auto getPattern(int id) const
bool isGroup(int id) const
NoiseMap class for the ITS and MFT.
bool isNoisy(int chip, int row, int col) const
GLboolean GLboolean GLboolean b
GLenum GLuint GLint GLint layer
GLboolean GLboolean GLboolean GLboolean a
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
wrapper for the Entropy-encoded clusters of the TF
Compressed but not yet entropy-encoded clusters.
std::vector< int16_t > chipInc
number of clusters in ROF
std::vector< int16_t > bcIncROF
1st chip ID in the ROF
std::vector< int32_t > orbitIncROF
increment of ROF BC wrt BC of previous ROF
std::vector< uint16_t > pattID
increment of pixel column wrt that of prev. pixel (sometimes can be slightly negative)
std::vector< uint16_t > firstChipROF
std::vector< uint32_t > nclusROF
increment of ROF orbit wrt orbit of previous ROF
std::vector< uint8_t > pattMap
cluster pattern ID
std::vector< uint16_t > row
clusters in chip
std::vector< int16_t > colInc
row of fired pixel
std::vector< uint16_t > chipMul
increment of chipID wrt that of prev. chip
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()))
std::vector< unsigned char > pattVec
std::vector< CompClusterExt > cclusVec