16#ifndef O2_ITSMFT_CTFCODER_H
17#define O2_ITSMFT_CTFCODER_H
52 template <typename VEC>
57 template <typename VROF, typename VCLUS, typename VPAT>
61 template <typename VROF, typename VDIG>
75 template <typename VROF, typename VCLUS, typename VPAT>
79 template <typename VROF, typename VDIG>
82 void appendToTree(TTree&
tree,
CTF& ec);
87template <typename VEC>
108 auto szIni = estimateCompressedSize(compCl);
114 ec->setHeader(compCl.header);
119#define ENCODEITSMFT(part, slot, bits) CTF::get(buff.data())->encode(part, int(slot), bits, optField[int(slot)], &buff, mCoders[int(slot)], getMemMarginFactor());
139template <
typename VROF,
typename VCLUS,
typename VPAT>
143 auto compCl = decodeCompressedClusters(ec, iosize);
150template <
typename VROF,
typename VDIG>
154 auto compCl = decodeCompressedClusters(ec, iosize);
155 decompress(compCl, rofRecVec, digVec, noiseMap,
clPattLookup);
161template <
typename VROF,
typename VCLUS,
typename VPAT>
172 uint32_t clCount = 0, chipCount = 0;
173 auto pattIt = compCl.
pattMap.begin();
174 auto pattItStored = pattIt;
179 auto clusterize = [&](uint16_t chipID, int16_t
row, int16_t
col,
int leftFired) {
180#ifdef _ALLOW_DIAGONAL_ALPIDE_CLUSTERS_
181 const std::array<int16_t, 8> walkRow = {1, -1, 0, 0, 1, 1, -1, -1};
182 const std::array<int16_t, 8> walkCol = {0, 0, -1, 1, 1, -1, 1, 1};
184 const std::array<int16_t, 4> walkRow = {1, -1, 0, 0};
185 const std::array<int16_t, 4> walkCol = {0, 0, -1, 1};
187 Clusterer::BBox
bbox(chipID);
189 std::function<
bool(int16_t, int16_t)> checkPixelAndNeighbours = [&](int16_t ir1, int16_t ic1) {
191 auto checkPixel = [&](int16_t ir1, int16_t ic1) {
192 if (pmat[ir1][ic1]) {
193 pmat[ir1][ic1] =
false;
194 uint16_t
r =
row + ir1 - 1,
c =
col + ic1 - 1;
195 firedPixBuff.emplace_back(
r,
c);
203 if (checkPixel(ir1, ic1) && leftFired) {
205 while (checkPixelAndNeighbours(ir1 + walkRow[iw], ic1 + walkCol[iw]) && ++iw < walkRow.size()) {
212 firedPixBuff.clear();
213 for (
auto s : maskedPixBuff) {
216 checkPixelAndNeighbours(
s.getRowDirect() + walkRow[iw],
s.getCol() + walkCol[iw]);
217 if (!firedPixBuff.empty()) {
218 bbox.chipID = chipID;
220 firedPixBuff.clear();
223 }
while (leftFired && ++iw < walkRow.size());
230 auto reclusterize = [&]() {
234 auto pattItPrev = pattIt;
235 maskedPixBuff.clear();
236 int rowRef = clus.getRow(), colRef = clus.getCol();
238 throw std::runtime_error(
"Clusters contain pattern IDs, but no dictionary is provided...");
244 float xCOG = 0, zCOG = 0;
246 rowRef -= round(xCOG);
247 colRef -= round(zCOG);
252 if (rowSpan == 1 && colSpan == 1) {
253 if (noiseMap->
isNoisy(clus.getChipID(), rowRef, colRef)) {
254 std::copy(pattItStored, pattItPrev, back_inserter(
pattVec));
255 pattItStored = pattIt;
261 for (
int ir = 0;
ir < rowSpan;
ir++) {
262 int row = rowRef +
ir;
263 for (
int ic = 0; ic < colSpan; ic++) {
265 if (noiseMap->
isNoisy(clus.getChipID(),
row, colRef + ic)) {
266 maskedPixBuff.emplace_back(
ir + 1, ic + 1);
267 pmat[
ir + 1][ic + 1] =
false;
270 pmat[
ir + 1][ic + 1] =
true;
274 pmat[
ir + 1][ic + 1] =
false;
281 std::copy(pattItStored, pattItPrev, back_inserter(
pattVec));
282 pattItStored = pattIt;
284 clusterize(clus.getChipID(), rowRef, colRef, nPixels);
291 for (uint32_t irof = 0; irof < compCl.
header.
nROFs; irof++) {
293 auto& rofRec = rofRecVec[irof];
300 rofRec.setBCData(prevIR);
301 rofRec.setFirstEntry(
cclusVec.size());
307 for (uint32_t icl = 0; icl < compCl.
nclusROF[irof]; icl++) {
308 auto& clus =
cclusVec.emplace_back();
309 if (inChip++ < compCl.
chipMul[chipCount]) {
310 clus.setCol((
col += compCl.
colInc[clCount]));
312 chipID += compCl.
chipInc[++chipCount];
314 clus.setCol((
col = compCl.
colInc[clCount]));
316 clus.setRow(compCl.
row[clCount]);
317 clus.setPatternID(compCl.
pattID[clCount]);
318 clus.setChipID(chipID);
327 rofRec.setNEntries(
cclusVec.size() - rofRec.getFirstEntry());
330 if (pattItStored != pattIt) {
331 std::copy(pattItStored, pattIt, back_inserter(
pattVec));
340 LOG(error) <<
"expected " << compCl.
header.
nClusters <<
" but counted " << clCount <<
" in ROFRecords";
341 throw std::runtime_error(
"mismatch between expected and counter number of clusters");
346template <
typename VROF,
typename VDIG>
347void CTFCoder::decompress(
const CompressedClusters& compCl, VROF& rofRecVec, VDIG& digVec,
const NoiseMap* noiseMap,
const LookUp&
clPattLookup)
349 rofRecVec.resize(compCl.header.nROFs);
350 digVec.reserve(compCl.header.nClusters * 2);
352 uint32_t clCount = 0, chipCount = 0;
353 auto pattIt = compCl.pattMap.begin();
355 for (uint32_t irof = 0; irof < compCl.header.nROFs; irof++) {
356 size_t chipStartNDig = digVec.size();
358 auto& rofRec = rofRecVec[irof];
359 if (compCl.orbitIncROF[irof]) {
360 prevIR.bc = compCl.bcIncROF[irof];
361 prevIR.orbit += compCl.orbitIncROF[irof];
363 prevIR.bc += compCl.bcIncROF[irof];
365 rofRec.setBCData(prevIR);
366 rofRec.setFirstEntry(digVec.size());
369 uint16_t chipID = compCl.firstChipROF[irof],
col = 0;
371 for (uint32_t icl = 0; icl < compCl.nclusROF[irof]; icl++) {
372 if (inChip++ < compCl.chipMul[chipCount]) {
373 col += compCl.colInc[clCount];
376 auto added = digVec.size() - chipStartNDig;
378 std::sort(digVec.end() - added, digVec.end(),
379 [](Digit&
a, Digit&
b) { return a.getColumn() < b.getColumn() || (a.getColumn() == b.getColumn() && a.getRow() < b.getRow()); });
381 chipStartNDig = digVec.size();
382 chipID += compCl.chipInc[++chipCount];
383#ifdef _CHECK_INCREMENTES_
384 if (int16_t(compCl.chipInc[chipCount]) < 0) {
385 LOG(warning) <<
"Negative chip increment " << int16_t(compCl.chipInc[chipCount]) <<
" -> " << chipID;
389 col = compCl.colInc[clCount];
391 uint16_t rowRef = compCl.row[clCount], colRef =
col;
392 auto pattID = compCl.pattID[clCount];
397 throw std::runtime_error(
"Clusters contain pattern IDs, but no dictionary is provided...");
403 float xCOG = 0., zCOG = 0.;
405 rowRef -= round(xCOG);
406 colRef -= round(zCOG);
413 auto fillRowCol = [&digVec, chipID, rowRef, colRef, noiseMap](
int r,
int c) {
416 if (noiseMap && noiseMap->isNoisy(chipID,
r,
c)) {
419 digVec.emplace_back(chipID, uint16_t(
r), uint16_t(
c));
423 auto added = digVec.size() - chipStartNDig;
425 std::sort(digVec.end() - added, digVec.end(),
426 [](Digit&
a, Digit&
b) { return a.getColumn() < b.getColumn() || (a.getColumn() == b.getColumn() && a.getRow() < b.getRow()); });
429 if (compCl.nclusROF[irof]) {
432 rofRec.setNEntries(digVec.size() - rofRec.getFirstEntry());
435 assert(pattIt == compCl.pattMap.end());
436 assert(chipCount == compCl.header.nChips);
438 if (clCount != compCl.header.nClusters) {
439 LOG(error) <<
"expected " << compCl.header.nClusters <<
" but counted " << clCount <<
" in ROFRecords";
440 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.
ctf::ANSHeader mANSVersion
virtual void assignDictVersion(CTFDictHeader &h) const
<<======================== 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.
std::vector< PixelData > RowColBuff
std::array< std::array< bool, ClusterPattern::MaxRowSpan+2 >, ClusterPattern::MaxColSpan+2 > PMatrix
void createCoders(const std::vector< char > &bufVec, o2::ctf::CTFCoderBase::OpType op) final
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 strobeLength)
entropy-encode clusters to buffer with CTF
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
CTFCoder(o2::ctf::CTFCoderBase::OpType op, o2::detectors::DetID det)
~CTFCoder() final=default
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
const std::array< unsigned char, kExtendedPatternBytes > & getPattern() const
Returns the pattern.
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
NoiseMap class for the ITS and MFT.
bool isNoisy(int chip, int row, int col) const
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
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