@@ -160,8 +160,27 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc)
160160 auto & allVerticesLabels = mIsMC ? pc.outputs ().make <std::vector<o2::MCCompLabel>>(Output{" ITS" , " VERTICESMCTR" , 0 }) : dummyMCLabVerts;
161161 auto & allVerticesPurities = mIsMC ? pc.outputs ().make <std::vector<float >>(Output{" ITS" , " VERTICESMCPUR" , 0 }) : dummyMCPurVerts;
162162
163+ const auto clock = mTimeFrame ->getROFOverlapTableView ().getClock ();
164+ const auto & clockLayer = mTimeFrame ->getROFOverlapTableView ().getClockLayer ();
165+ auto setBCData = [&](auto & rofs) {
166+ for (size_t iROF{0 }; iROF < rofs.size (); ++iROF) { // set BC data
167+ auto & rof = rofs[iROF];
168+ int orb = (iROF * par.getROFLengthInBC (clock) / o2::constants::lhc::LHCMaxBunches) + tfInfo.firstTForbit ;
169+ int bc = (iROF * par.getROFLengthInBC (clock) % o2::constants::lhc::LHCMaxBunches) + par.getROFDelayInBC (clock);
170+ o2::InteractionRecord ir (bc, orb);
171+ rof.setBCData (ir);
172+ rof.setROFrame (iROF);
173+ rof.setNEntries (0 );
174+ rof.setFirstEntry (-1 );
175+ }
176+ };
177+
163178 if (!hasClusters) {
164179 // skip processing if no data is received entirely but still create empty output so consumers do not wait
180+ allTrackROFs.resize (clockLayer.mNROFsTF );
181+ vertROFvec.resize (clockLayer.mNROFsTF );
182+ setBCData (allTrackROFs);
183+ setBCData (vertROFvec);
165184 return ;
166185 }
167186
@@ -269,86 +288,70 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc)
269288 if (mTimeFrame ->hasBogusClusters ()) {
270289 LOG (warning) << fmt::format (" + The processed timeframe had {} clusters with wild z coordinates, check the dictionaries" , mTimeFrame ->hasBogusClusters ());
271290 }
291+ }
272292
273- auto & tracks = mTimeFrame ->getTracks ();
274- allTrackLabels.reserve (mTimeFrame ->getTracksLabel ().size ()); // should be 0 if not MC
275- std::copy (mTimeFrame ->getTracksLabel ().begin (), mTimeFrame ->getTracksLabel ().end (), std::back_inserter (allTrackLabels));
276- {
277- // create the track to clock ROF association here
278- // the clock ROF is just the fastest ROF
279- // the number of ROFs does not necessarily reflect the actual ROFs
280- // due to possible delay of other layers, however it is guaranteed to be >=0
281- // tracks are guaranteed to be sorted here by their lower edge
282- const auto & clock = mTimeFrame ->getROFOverlapTableView ().getClock ();
283- const auto & clockLayer = mTimeFrame ->getROFOverlapTableView ().getClockLayer ();
284- auto setBCData = [&](auto & rofs) {
285- for (size_t iROF{0 }; iROF < rofs.size (); ++iROF) { // set BC data
286- auto & rof = rofs[iROF];
287- int orb = (iROF * par.getROFLengthInBC (clock) / o2::constants::lhc::LHCMaxBunches) + tfInfo.firstTForbit ;
288- int bc = (iROF * par.getROFLengthInBC (clock) % o2::constants::lhc::LHCMaxBunches) + par.getROFDelayInBC (clock);
289- o2::InteractionRecord ir (bc, orb);
290- rof.setBCData (ir);
291- rof.setROFrame (iROF);
292- rof.setNEntries (0 );
293- rof.setFirstEntry (-1 );
294- }
295- };
296- // we pick whatever is the largest possible number of rofs since there might be tracks/vertices which are beyond
297- // the clock layer
298- int highestROF{0 };
299- for (const auto & trc : tracks) {
300- highestROF = std::max (highestROF, (int )clockLayer.getROF (trc.getTimeStamp ()));
301- }
302- for (const auto & vtx : vertices) {
303- highestROF = std::max (highestROF, (int )clockLayer.getROF (vtx.getTimeStamp ().lower ()));
304- }
305- highestROF = std::max (highestROF, (int )clockLayer.mNROFsTF );
306- allTrackROFs.resize (highestROF);
307- vertROFvec.resize (highestROF);
308- setBCData (allTrackROFs);
309- setBCData (vertROFvec);
310-
311- mTimeFrame ->useMultiplictyMask (); // use multiplicty selection for IR frames
312-
313- std::vector<int > rofEntries (highestROF + 1 , 0 );
314- for (unsigned int iTrk{0 }; iTrk < tracks.size (); ++iTrk) {
315- auto & trc{tracks[iTrk]};
316- trc.setFirstClusterEntry ((int )allClusIdx.size ()); // before adding tracks, create final cluster indices
317- int ncl = trc.getNumberOfClusters (), nclf = 0 ;
318- for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!!
319- auto clid = trc.getClusterIndex (ic);
320- if (clid >= 0 ) {
321- trc.setClusterSize (ic, mTimeFrame ->getClusterSize ((mDoStaggering ) ? ic : 0 , clid));
322- allClusIdx.push_back (clid);
323- nclf++;
324- }
325- }
326- assert (ncl == nclf);
327- allTracks.emplace_back (trc);
328- auto rof = clockLayer.getROF (trc.getTimeStamp ());
329- ++rofEntries[rof];
330- }
331- std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
332- for (size_t iROF{0 }; iROF < allTrackROFs.size (); ++iROF) {
333- allTrackROFs[iROF].setFirstEntry (rofEntries[iROF]);
334- allTrackROFs[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
335- if (mTimeFrame ->getROFMaskView ().isROFEnabled (clockLayerId, (int )iROF)) {
336- auto & irFrame = irFrames.emplace_back (allTrackROFs[iROF].getBCData (), allTrackROFs[iROF].getBCData () + clockLayer.mROFLength - 1 );
337- irFrame.info = allTrackROFs[iROF].getNEntries ();
338- }
339- }
340- // same thing for vertices rofs
341- std::fill (rofEntries.begin (), rofEntries.end (), 0 );
342- for (const auto & vtx : vertices) {
343- auto rof = clockLayer.getROF (vtx.getTimeStamp ().lower ());
344- ++rofEntries[rof];
345- }
346- std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
347- for (size_t iROF{0 }; iROF < vertROFvec.size (); ++iROF) {
348- vertROFvec[iROF].setFirstEntry (rofEntries[iROF]);
349- vertROFvec[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
293+ auto & tracks = mTimeFrame ->getTracks ();
294+ allTrackLabels.reserve (mTimeFrame ->getTracksLabel ().size ()); // should be 0 if not MC
295+ std::copy (mTimeFrame ->getTracksLabel ().begin (), mTimeFrame ->getTracksLabel ().end (), std::back_inserter (allTrackLabels));
296+ // create the track to clock ROF association here
297+ // the clock ROF is just the fastest ROF
298+ // the number of ROFs does not necessarily reflect the actual ROFs
299+ // due to possible delay of other layers, however it is guaranteed to be >=0
300+ // tracks are guaranteed to be sorted here by their lower edge
301+ // we pick whatever is the largest possible number of rofs since there might be tracks/vertices which are beyond
302+ // the clock layer
303+ int highestROF{0 };
304+ for (const auto & trc : tracks) {
305+ highestROF = std::max (highestROF, (int )clockLayer.getROF (trc.getTimeStamp ()));
306+ }
307+ for (const auto & vtx : vertices) {
308+ highestROF = std::max (highestROF, (int )clockLayer.getROF (vtx.getTimeStamp ().lower ()));
309+ }
310+ highestROF = std::max (highestROF, (int )clockLayer.mNROFsTF );
311+ allTrackROFs.resize (highestROF);
312+ vertROFvec.resize (highestROF);
313+ setBCData (allTrackROFs);
314+ setBCData (vertROFvec);
315+
316+ mTimeFrame ->useMultiplictyMask (); // use multiplicty selection for IR frames
317+
318+ std::vector<int > rofEntries (highestROF + 1 , 0 );
319+ for (unsigned int iTrk{0 }; iTrk < tracks.size (); ++iTrk) {
320+ auto & trc{tracks[iTrk]};
321+ trc.setFirstClusterEntry ((int )allClusIdx.size ()); // before adding tracks, create final cluster indices
322+ int ncl = trc.getNumberOfClusters (), nclf = 0 ;
323+ for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!!
324+ auto clid = trc.getClusterIndex (ic);
325+ if (clid >= 0 ) {
326+ trc.setClusterSize (ic, mTimeFrame ->getClusterSize ((mDoStaggering ) ? ic : 0 , clid));
327+ allClusIdx.push_back (clid);
328+ nclf++;
350329 }
351330 }
331+ assert (ncl == nclf);
332+ allTracks.emplace_back (trc);
333+ auto rof = clockLayer.getROF (trc.getTimeStamp ());
334+ ++rofEntries[rof];
335+ }
336+ std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
337+ for (size_t iROF{0 }; iROF < allTrackROFs.size (); ++iROF) {
338+ allTrackROFs[iROF].setFirstEntry (rofEntries[iROF]);
339+ allTrackROFs[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
340+ if (mTimeFrame ->getROFMaskView ().isROFEnabled (clockLayerId, (int )iROF)) {
341+ auto & irFrame = irFrames.emplace_back (allTrackROFs[iROF].getBCData (), allTrackROFs[iROF].getBCData () + clockLayer.mROFLength - 1 );
342+ irFrame.info = allTrackROFs[iROF].getNEntries ();
343+ }
344+ }
345+ // same thing for vertices rofs
346+ std::fill (rofEntries.begin (), rofEntries.end (), 0 );
347+ for (const auto & vtx : vertices) {
348+ auto rof = clockLayer.getROF (vtx.getTimeStamp ().lower ());
349+ ++rofEntries[rof];
350+ }
351+ std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
352+ for (size_t iROF{0 }; iROF < vertROFvec.size (); ++iROF) {
353+ vertROFvec[iROF].setFirstEntry (rofEntries[iROF]);
354+ vertROFvec[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
352355 }
353356
354357 LOGP (info, " ITSTracker pushed {} tracks in {} rofs and {} vertices {}" , allTracks.size (), allTrackROFs.size (), vertices.size (), ((mDoStaggering ) ? " in staggered-readout mode" : " " ));
0 commit comments