3737#include " CommonConstants/LHCConstants.h"
3838#include " DataFormatsTPC/Digit.h"
3939#include " TPCBase/RDHUtils.h"
40+ #include " TPCBase/CRU.h"
4041#include " DetectorsRaw/RDHUtils.h"
4142#endif
4243
@@ -191,11 +192,11 @@ struct zsEncoder {
191192 int curRegion = 0 ;
192193 unsigned int encodeBits = 0 ;
193194 unsigned int zsVersion = 0 ;
194- unsigned int iSector;
195- o2::raw::RawFileWriter* raw;
196- const o2::InteractionRecord* ir;
197- const GPUParam& param;
198- bool padding;
195+ unsigned int iSector = 0 ;
196+ o2::raw::RawFileWriter* raw = nullptr ;
197+ const o2::InteractionRecord* ir = nullptr ;
198+ const GPUParam* param = nullptr ;
199+ bool padding = false ;
199200 int lastEndpoint = -2 , lastTime = -1 , lastRow = GPUCA_ROW_COUNT ;
200201 int endpoint = 0 ;
201202 long hbf = -1 , nexthbf = 0 ;
@@ -261,7 +262,7 @@ struct zsEncoderRow : public zsEncoder {
261262
262263 bool checkInput (std::vector<o2::tpc::Digit>& tmpBuffer, unsigned int k);
263264 bool writeSubPage ();
264- void init () {}
265+ void init () { encodeBits = zsVersion == 2 ? TPCZSHDR :: TPC_ZS_NBITS_V2 : TPCZSHDR :: TPC_ZS_NBITS_V1 ; }
265266 void initPage () {}
266267 unsigned int encodeSequence (std::vector<o2::tpc::Digit>& tmpBuffer, unsigned int k);
267268
@@ -271,10 +272,10 @@ struct zsEncoderRow : public zsEncoder {
271272
272273inline bool zsEncoderRow::sort (const o2::tpc::Digit a, const o2::tpc::Digit b)
273274{
274- int endpointa = param. tpcGeometry .GetRegion (a.getRow ());
275- int endpointb = param. tpcGeometry .GetRegion (b.getRow ());
276- endpointa = 2 * endpointa + (a.getRow () >= param. tpcGeometry .GetRegionStart (endpointa) + param. tpcGeometry .GetRegionRows (endpointa) / 2 );
277- endpointb = 2 * endpointb + (b.getRow () >= param. tpcGeometry .GetRegionStart (endpointb) + param. tpcGeometry .GetRegionRows (endpointb) / 2 );
275+ int endpointa = param-> tpcGeometry .GetRegion (a.getRow ());
276+ int endpointb = param-> tpcGeometry .GetRegion (b.getRow ());
277+ endpointa = 2 * endpointa + (a.getRow () >= param-> tpcGeometry .GetRegionStart (endpointa) + param-> tpcGeometry .GetRegionRows (endpointa) / 2 );
278+ endpointb = 2 * endpointb + (b.getRow () >= param-> tpcGeometry .GetRegionStart (endpointb) + param-> tpcGeometry .GetRegionRows (endpointb) / 2 );
278279 if (endpointa != endpointb) {
279280 return endpointa <= endpointb;
280281 }
@@ -291,11 +292,11 @@ bool zsEncoderRow::checkInput(std::vector<o2::tpc::Digit>& tmpBuffer, unsigned i
291292{
292293 seqLen = 1 ;
293294 if (lastRow != tmpBuffer[k].getRow ()) {
294- endpointStart = param. tpcGeometry .GetRegionStart (curRegion);
295+ endpointStart = param-> tpcGeometry .GetRegionStart (curRegion);
295296 endpoint = curRegion * 2 ;
296- if (tmpBuffer[k].getRow () >= endpointStart + param. tpcGeometry .GetRegionRows (curRegion) / 2 ) {
297+ if (tmpBuffer[k].getRow () >= endpointStart + param-> tpcGeometry .GetRegionRows (curRegion) / 2 ) {
297298 endpoint++;
298- endpointStart += param. tpcGeometry .GetRegionRows (curRegion) / 2 ;
299+ endpointStart += param-> tpcGeometry .GetRegionRows (curRegion) / 2 ;
299300 }
300301 }
301302 for (unsigned int l = k + 1 ; l < tmpBuffer.size (); l++) {
@@ -404,7 +405,7 @@ void zsEncoderRow::decodePage(std::vector<o2::tpc::Digit>& outputBuffer, const z
404405 if ((unsigned int )region != decEndpoint / 2 ) {
405406 throw std::runtime_error (" CRU ID / endpoint mismatch" );
406407 }
407- int nRowsRegion = param. tpcGeometry .GetRegionRows (region);
408+ int nRowsRegion = param-> tpcGeometry .GetRegionRows (region);
408409
409410 int timeBin = (decHDR->timeOffset + (unsigned long )(o2::raw::RDHUtils::getHeartBeatOrbit (*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN ;
410411 for (int l = 0 ; l < decHDR->nTimeBins ; l++) {
@@ -416,7 +417,7 @@ void zsEncoderRow::decodePage(std::vector<o2::tpc::Digit>& outputBuffer, const z
416417 if (tbHdr->rowMask != 0 && ((upperRows) ^ ((decEndpoint & 1 ) != 0 ))) {
417418 throw std::runtime_error (" invalid endpoint" );
418419 }
419- const int rowOffset = param. tpcGeometry .GetRegionStart (region) + (upperRows ? (nRowsRegion / 2 ) : 0 );
420+ const int rowOffset = param-> tpcGeometry .GetRegionStart (region) + (upperRows ? (nRowsRegion / 2 ) : 0 );
420421 const int nRows = upperRows ? (nRowsRegion - nRowsRegion / 2 ) : (nRowsRegion / 2 );
421422 const int nRowsUsed = __builtin_popcount ((unsigned int )(tbHdr->rowMask & 0x7FFF ));
422423 decPagePtr += nRowsUsed ? (2 * nRowsUsed) : 2 ;
@@ -474,6 +475,7 @@ struct zsEncoderLinkBased : public zsEncoder {
474475
475476void zsEncoderLinkBased::init ()
476477{
478+ encodeBits = TPCZSHDRV2 ::TPC_ZS_NBITS_V3 ;
477479 for (int i = 0 ; i < 5 ; i++) {
478480 for (int j = 0 ; j < 32 ; j++) {
479481 inverseChannelMapping[i][j] = -1 ;
@@ -516,7 +518,7 @@ void zsEncoderLinkBased::createBitmask(std::vector<o2::tpc::Digit>& tmpBuffer, u
516518 unsigned int l;
517519 for (l = k; l < tmpBuffer.size (); l++) {
518520 const auto & a = tmpBuffer[l];
519- int cruinsector = param. tpcGeometry .GetRegion (a.getRow ());
521+ int cruinsector = param-> tpcGeometry .GetRegion (a.getRow ());
520522 o2::tpc::GlobalPadNumber pad = mapper.globalPadNumber (o2::tpc::PadPos (a.getRow (), a.getPad ()));
521523 o2::tpc::FECInfo fec = mapper.fecInfo (pad);
522524 o2::tpc::CRU cru = cruinsector;
@@ -547,8 +549,8 @@ bool zsEncoderLinkBased::writeSubPage()
547549bool zsEncoderLinkBased::sort (const o2::tpc::Digit a, const o2::tpc::Digit b)
548550{
549551 // Fixme: this is blasphemy... one shoult precompute all values and sort an index array
550- int cruinsectora = param. tpcGeometry .GetRegion (a.getRow ());
551- int cruinsectorb = param. tpcGeometry .GetRegion (b.getRow ());
552+ int cruinsectora = param-> tpcGeometry .GetRegion (a.getRow ());
553+ int cruinsectorb = param-> tpcGeometry .GetRegion (b.getRow ());
552554 if (cruinsectora != cruinsectorb) {
553555 return cruinsectora < cruinsectorb;
554556 }
@@ -727,7 +729,7 @@ bool zsEncoderDenseLinkBased::checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
727729 unsigned int sizeChk = (unsigned int )(pagePtr - reinterpret_cast <unsigned char *>(page));
728730 sizeChk += 3 * sizeof (char ); // timebin + linkID + linkCounter
729731 sizeChk += 80 / 8 ; // bitmask
730- sizeChk += (nSamples * TPCZSHDRV2 :: TPC_ZS_NBITS_V4 + 7 ) / 8 ;
732+ sizeChk += (nSamples * encodeBits + 7 ) / 8 ;
731733 if (sizeChk > TPCZSHDR ::TPC_ZS_PAGE_SIZE ) {
732734 finishPage = true ;
733735 }
@@ -777,7 +779,7 @@ unsigned int zsEncoderDenseLinkBased::encodeSequence(std::vector<o2::tpc::Digit>
777779 }
778780 }
779781
780- static_assert (TPCZSHDRV2 ::TPC_ZS_NBITS_V4 == 12 );
782+ static_assert (TPCZSHDRV2 ::TPC_ZS_NBITS_V3 == 12 );
781783 unsigned int nStreaming = nSamples;
782784 if (free4bitPointer) {
783785 nStreaming--;
@@ -858,7 +860,7 @@ void zsEncoderDenseLinkBased::decodePage(std::vector<o2::tpc::Digit>& outputBuff
858860 decPagePtr += sizeof (unsigned char );
859861 }
860862 const unsigned char * adcData = (const unsigned char *)(decPagePtr);
861- decPagePtr += (nADC * TPCZSHDRV2 :: TPC_ZS_NBITS_V4 + 7 ) / 8 ;
863+ decPagePtr += (nADC * encodeBits + 7 ) / 8 ;
862864 unsigned int byte = 0 , bits = 0 , posXbits = 0 ;
863865 while (posXbits < nADC) {
864866 byte |= *(adcData++) << bits;
@@ -941,7 +943,6 @@ inline unsigned int zsEncoderRun<T>::run(std::vector<zsPage>* buffer, std::vecto
941943 int rawendpoint = 0 ;
942944 (void )(rawcru + rawendpoint); // avoid compiler warning
943945 encodeBitsFactor = (1 << (encodeBits - 10 ));
944- init ();
945946
946947 std::sort (tmpBuffer.begin (), tmpBuffer.end (), [this ](const o2::tpc::Digit a, const o2::tpc::Digit b) { return sort (a, b); });
947948 for (unsigned int k = 0 ; k <= tmpBuffer.size (); k++) {
@@ -958,7 +959,7 @@ inline unsigned int zsEncoderRun<T>::run(std::vector<zsPage>* buffer, std::vecto
958959 }
959960 }
960961 if (lastRow != tmpBuffer[k].getRow ()) {
961- curRegion = param. tpcGeometry .GetRegion (tmpBuffer[k].getRow ());
962+ curRegion = param-> tpcGeometry .GetRegion (tmpBuffer[k].getRow ());
962963 }
963964 mustWriteSubPage = checkInput (tmpBuffer, k);
964965 } else {
@@ -1110,26 +1111,23 @@ void GPUReconstructionConvert::RunZSEncoder(const S& in, std::unique_ptr<unsigne
11101111
11111112 auto runZS = [&](auto & encoder) {
11121113 encoder.zsVersion = version;
1114+ encoder.init ();
11131115 totalPages += encoder.run (buffer[i], tmpBuffer);
11141116 if (verify) {
11151117 nErrors += encoder.compare (buffer[i], tmpBuffer); // Verification
11161118 }
11171119 };
11181120
11191121 if (version >= 1 && version <= 2 ) {
1120- bool zs12bit = version == 2 ;
1121- zsEncoderRun<zsEncoderRow> enc{{{.iSector = i, .raw = raw, .ir = ir, .param = param, .padding = padding}}};
1122- enc.encodeBits = zs12bit ? TPCZSHDR ::TPC_ZS_NBITS_V2 : TPCZSHDR ::TPC_ZS_NBITS_V1 ;
1122+ zsEncoderRun<zsEncoderRow> enc{{{.iSector = i, .raw = raw, .ir = ir, .param = ¶m, .padding = padding}}};
11231123 runZS (enc);
11241124 } else if (version >= 3 || version <= 4 ) {
11251125#ifdef GPUCA_O2_LIB
11261126 if (version == 3 ) {
1127- zsEncoderRun<zsEncoderImprovedLinkBased> enc{{{{.iSector = i, .raw = raw, .ir = ir, .param = param, .padding = padding}}}};
1128- enc.encodeBits = TPCZSHDRV2 ::TPC_ZS_NBITS_V3 ;
1127+ zsEncoderRun<zsEncoderImprovedLinkBased> enc{{{{.iSector = i, .raw = raw, .ir = ir, .param = ¶m, .padding = padding}}}};
11291128 runZS (enc);
11301129 } else if (version == 4 ) {
1131- zsEncoderRun<zsEncoderDenseLinkBased> enc{{{{.iSector = i, .raw = raw, .ir = ir, .param = param, .padding = padding}}}};
1132- enc.encodeBits = TPCZSHDRV2 ::TPC_ZS_NBITS_V4 ;
1130+ zsEncoderRun<zsEncoderDenseLinkBased> enc{{{{.iSector = i, .raw = raw, .ir = ir, .param = ¶m, .padding = padding}}}};
11331131 runZS (enc);
11341132 }
11351133#else
@@ -1205,3 +1203,56 @@ void GPUReconstructionConvert::RunZSFilter(std::unique_ptr<o2::tpc::Digit[]>* bu
12051203 }
12061204#endif
12071205}
1206+
1207+ #ifdef GPUCA_O2_LIB
1208+ template <class T >
1209+ static inline auto GetDecoder_internal (const GPUParam& param, int version)
1210+ {
1211+ std::shared_ptr<T> enc = std::make_shared<T>();
1212+ enc->param = ¶m;
1213+ enc->zsVersion = version;
1214+ enc->init ();
1215+ return [enc](std::vector<o2::tpc::Digit>& outBuffer, const void * page, unsigned int firstTfOrbit) {
1216+ const o2::header::RAWDataHeader& rdh = *(const o2::header::RAWDataHeader*)page;
1217+ if (o2::raw::RDHUtils::getMemorySize (rdh) == sizeof (o2::header::RAWDataHeader)) {
1218+ return ;
1219+ }
1220+ if (o2::raw::RDHUtils::getDetectorField (rdh) != 2 ) {
1221+ return ;
1222+ }
1223+ o2::tpc::CRU cru (o2::tpc::rdh_utils::getCRU (rdh));
1224+ enc->iSector = cru.sector ();
1225+ int endpoint = cru.region () * 2 + o2::tpc::rdh_utils::getEndPoint (rdh);
1226+ enc->decodePage (outBuffer, (const zsPage*)page, endpoint, firstTfOrbit);
1227+ };
1228+ }
1229+
1230+ std::function<void (std::vector<o2::tpc::Digit>&, const void *, unsigned int )> GPUReconstructionConvert::GetDecoder (int version, const GPUParam& param)
1231+ {
1232+ if (version >= 1 && version <= 2 ) {
1233+ return GetDecoder_internal<zsEncoderRow>(param, version);
1234+ } else if (version == 3 ) {
1235+ return GetDecoder_internal<zsEncoderImprovedLinkBased>(param, version);
1236+ } else if (version == 4 ) {
1237+ return GetDecoder_internal<zsEncoderDenseLinkBased>(param, version);
1238+ } else {
1239+ throw std::runtime_error (" Invalid ZS version" );
1240+ }
1241+ }
1242+
1243+ void GPUReconstructionZSDecoder::DecodePage (std::vector<o2::tpc::Digit>& outputBuffer, const void * page, unsigned int tfFirstOrbit, const GPUParam& param)
1244+ {
1245+ const o2::header::RAWDataHeader* rdh = (const o2::header::RAWDataHeader*)page;
1246+ if (o2::raw::RDHUtils::getMemorySize (*rdh) == sizeof (o2::header::RAWDataHeader)) {
1247+ return ;
1248+ }
1249+ const TPCZSHDR * const hdr = (const TPCZSHDR *)((const char *)page + sizeof (o2::header::RAWDataHeader));
1250+ if (mDecoders .size () < hdr->version + 1 ) {
1251+ mDecoders .resize (hdr->version + 1 );
1252+ }
1253+ if (mDecoders [hdr->version ] == nullptr ) {
1254+ mDecoders [hdr->version ] = GPUReconstructionConvert::GetDecoder (hdr->version , param);
1255+ }
1256+ mDecoders [hdr->version ](outputBuffer, page, tfFirstOrbit);
1257+ }
1258+ #endif
0 commit comments