2424#include " CommonDataFormat/InteractionRecord.h"
2525#endif
2626#ifdef GPUCA_HAVE_O2HEADERS
27+ #include " GPUTriggerOutputs.h"
2728#include " GPUHostDataTypes.h"
2829#include " GPUTPCCFChainContext.h"
2930#include " DataFormatsTPC/ZeroSuppression.h"
@@ -198,6 +199,15 @@ std::pair<unsigned int, unsigned int> GPUChainTracking::TPCClusterizerDecodeZSCo
198199 const TPCZSHDR* const hdr = (const TPCZSHDR*)(rdh_utils::getLink (o2::raw::RDHUtils::getFEEID (*rdh)) == rdh_utils::DLBZSLinkID ? (page + o2::raw::RDHUtils::getMemorySize (*rdh) - sizeof (TPCZSHDRV2)) : (page + sizeof (o2::header::RAWDataHeader)));
199200 if (mCFContext ->zsVersion == -1 ) {
200201 mCFContext ->zsVersion = hdr->version ;
202+ if (GetProcessingSettings ().param .tpcTriggerHandling && mCFContext ->zsVersion < ZSVersion::ZSVersionDenseLinkBased) {
203+ GPUError (" Trigger handling only possible with TPC Dense Link Based data, received version %d" , mCFContext ->zsVersion );
204+ if (GetProcessingSettings ().ignoreNonFatalGPUErrors ) {
205+ mCFContext ->abandonTimeframe = true ;
206+ return {0 , 0 };
207+ } else {
208+ GPUFatal (" Cannot process with invalid TPC ZS data, exiting" );
209+ }
210+ }
201211 } else if (mCFContext ->zsVersion != (int )hdr->version ) {
202212 GPUError (" Received TPC ZS 8kb page of mixed versions, expected %d, received %d (linkid %d, feeCRU %d, feeEndpoint %d, feelinkid %d)" , mCFContext ->zsVersion , (int )hdr->version , (int )o2::raw::RDHUtils::getLinkID (*rdh), (int )rdh_utils::getCRU (*rdh), (int )rdh_utils::getEndPoint (*rdh), (int )rdh_utils::getLink (*rdh));
203213 constexpr size_t bufferSize = 3 * std::max (sizeof (*rdh), sizeof (*hdr)) + 1 ;
@@ -219,6 +229,15 @@ std::pair<unsigned int, unsigned int> GPUChainTracking::TPCClusterizerDecodeZSCo
219229 GPUFatal (" Cannot process with invalid TPC ZS data, exiting" );
220230 }
221231 }
232+ if (GetProcessingSettings ().param .tpcTriggerHandling ) {
233+ const TPCZSHDRV2* const hdr2 = (const TPCZSHDRV2*)hdr;
234+ if (hdr2->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) {
235+ const char * triggerWord = (const char *)hdr - TPCZSHDRV2::TRIGGER_WORD_SIZE;
236+ std::array<unsigned long , TPCZSHDRV2::TRIGGER_WORD_SIZE / sizeof (unsigned long )> tmp;
237+ memcpy ((void *)tmp.data (), triggerWord, TPCZSHDRV2::TRIGGER_WORD_SIZE);
238+ mTriggerBuffer ->triggers .emplace (tmp);
239+ }
240+ }
222241 nDigits += hdr->nADCsamples ;
223242 endpointAdcSamples[j] += hdr->nADCsamples ;
224243 unsigned int timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit (*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN;
@@ -459,6 +478,9 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers)
459478 if (mIOPtrs .tpcZS ) {
460479 unsigned int nDigitsFragmentMax[NSLICES];
461480 mCFContext ->zsVersion = -1 ;
481+ if (GetProcessingSettings ().param .tpcTriggerHandling ) {
482+ mTriggerBuffer ->triggers .clear ();
483+ }
462484 for (unsigned int iSlice = 0 ; iSlice < NSLICES; iSlice++) {
463485 if (mIOPtrs .tpcZS ->slice [iSlice].count [0 ]) {
464486 const void * rdh = mIOPtrs .tpcZS ->slice [iSlice].zsPtr [0 ][0 ];
@@ -484,6 +506,15 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers)
484506 processors ()->tpcClusterer [iSlice].mPmemory ->counters .nDigits = x.first ;
485507 mRec ->MemoryScalers ()->nTPCdigits += x.first ;
486508 }
509+ if (GetProcessingSettings ().param .tpcTriggerHandling ) {
510+ GPUOutputControl* triggerOutput = mSubOutputControls [GPUTrackingOutputs::getIndex (&GPUTrackingOutputs::tpcTriggerWords)];
511+ if (triggerOutput && triggerOutput->allocator ) {
512+ GPUInfo (" Storing %lu trigger words" , mTriggerBuffer ->triggers .size ());
513+ auto * outputBuffer = (decltype (mTriggerBuffer ->triggers )::value_type*)triggerOutput->allocator (mTriggerBuffer ->triggers .size () * sizeof (decltype (mTriggerBuffer ->triggers )::value_type));
514+ std::copy (mTriggerBuffer ->triggers .begin (), mTriggerBuffer ->triggers .end (), outputBuffer);
515+ }
516+ mTriggerBuffer ->triggers .clear ();
517+ }
487518 for (unsigned int iSlice = 0 ; iSlice < NSLICES; iSlice++) {
488519 unsigned int nDigitsBase = nDigitsFragmentMax[iSlice];
489520 unsigned int threshold = 40000000 ;
0 commit comments