@@ -351,49 +351,59 @@ int TimeFrameMixin<nLayers, Base>::loadROFrameData(const std::array<gsl::span<co
351351 this ->mClusterSize [iLayer].reserve (layerClusters[iLayer].size ());
352352 }
353353
354+ std::array<std::vector<size_t >, nLayers> patternOffsetsPerLayer;
354355 for (int iLayer{0 }; iLayer < nLayers; ++iLayer) {
355- const uint8_t * pattPtr = layerPatterns[iLayer].data ();
356- const uint8_t * pattEnd = pattPtr + layerPatterns[iLayer].size ();
356+ auto & offsets = patternOffsetsPerLayer[iLayer];
357+ offsets.resize (layerClusters[iLayer].size (), std::numeric_limits<size_t >::max ());
358+ size_t pattPos = 0 ;
359+ bool validPatterns = true ;
360+ for (size_t clusterId{0 }; clusterId < layerClusters[iLayer].size (); ++clusterId) {
361+ if (pattPos + 2 > layerPatterns[iLayer].size ()) {
362+ validPatterns = false ;
363+ break ;
364+ }
365+ offsets[clusterId] = pattPos;
366+ const uint8_t rowSpan = layerPatterns[iLayer][pattPos];
367+ const uint8_t colSpan = layerPatterns[iLayer][pattPos + 1 ];
368+ const size_t nBytes = (size_t (rowSpan) * colSpan + 7 ) / 8 ;
369+ if (pattPos + 2 + nBytes > layerPatterns[iLayer].size ()) {
370+ validPatterns = false ;
371+ break ;
372+ }
373+ pattPos += 2 + nBytes;
374+ }
375+ if (!validPatterns || pattPos != layerPatterns[iLayer].size ()) {
376+ LOGP (fatal, " Malformed TRK pattern stream for layer {}: {} bytes for {} clusters" ,
377+ iLayer, layerPatterns[iLayer].size (), layerClusters[iLayer].size ());
378+ }
379+ }
357380
381+ for (int iLayer{0 }; iLayer < nLayers; ++iLayer) {
358382 for (size_t iRof{0 }; iRof < layerROFs[iLayer].size (); ++iRof) {
359383 const auto & rof = layerROFs[iLayer][iRof];
360384 const int first = rof.getFirstEntry ();
361385 const int last = first + rof.getNEntries ();
362386
363387 for (int clusterId{first}; clusterId < last; ++clusterId) {
364- if (pattPtr + 2 > pattEnd) {
365- LOGP (error, " Pattern stream exhausted while decoding layer {} cluster {}" , iLayer, clusterId);
366- break ;
367- }
368- const uint8_t * pattForCluster = pattPtr;
369- const int nBytes = (pattForCluster[0 ] * pattForCluster[1 ] + 7 ) / 8 ;
370- if (pattPtr + 2 + nBytes > pattEnd) {
371- LOGP (error, " Pattern stream truncated for layer {} cluster {}" , iLayer, clusterId);
372- break ;
373- }
374- const int pattAdvance = 2 + nBytes;
375-
376388 if (clusterId < 0 || clusterId >= static_cast <int >(layerClusters[iLayer].size ())) {
377389 LOGP (warning, " Skipping out-of-range TRK cluster {} on layer {}" , clusterId, iLayer);
378- pattPtr += pattAdvance;
379390 continue ;
380391 }
381392
382393 const auto & c = layerClusters[iLayer][clusterId];
383394 if (c.subDetID < 0 || c.subDetID > 1 || c.disk != -1 ) {
384- pattPtr += pattAdvance;
385395 continue ;
386396 }
387397
388398 const int clusterLayer = startLayer[c.subDetID ] + c.layer ;
389399 if (clusterLayer != iLayer) {
390400 LOGP (error, " Skipping cluster from layer {} found in TRK layer stream {}" , clusterLayer, iLayer);
391- pattPtr += pattAdvance;
392401 continue ;
393402 }
394403
404+ const auto pattOffset = patternOffsetsPerLayer[iLayer][clusterId];
405+ const uint8_t * pattForCluster = layerPatterns[iLayer].data () + pattOffset;
395406 auto locXYZ = Clusterer::getClusterLocalCoordinates (c, pattForCluster, yPlaneMLOT);
396- pattPtr += pattAdvance;
397407
398408 const auto gloXYZ = geom->getMatrixL2G (c.chipID ) * locXYZ;
399409
0 commit comments