@@ -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
@@ -267,86 +286,70 @@ void ITSTrackingInterface::run(framework::ProcessingContext& pc)
267286 if (mTimeFrame ->hasBogusClusters ()) {
268287 LOG (warning) << fmt::format (" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries" , mTimeFrame ->hasBogusClusters ());
269288 }
289+ }
270290
271- auto & tracks = mTimeFrame ->getTracks ();
272- allTrackLabels.reserve (mTimeFrame ->getTracksLabel ().size ()); // should be 0 if not MC
273- std::copy (mTimeFrame ->getTracksLabel ().begin (), mTimeFrame ->getTracksLabel ().end (), std::back_inserter (allTrackLabels));
274- {
275- // create the track to clock ROF association here
276- // the clock ROF is just the fastest ROF
277- // the number of ROFs does not necessarily reflect the actual ROFs
278- // due to possible delay of other layers, however it is guaranteed to be >=0
279- // tracks are guaranteed to be sorted here by their lower edge
280- const auto & clock = mTimeFrame ->getROFOverlapTableView ().getClock ();
281- const auto & clockLayer = mTimeFrame ->getROFOverlapTableView ().getClockLayer ();
282- auto setBCData = [&](auto & rofs) {
283- for (size_t iROF{0 }; iROF < rofs.size (); ++iROF) { // set BC data
284- auto & rof = rofs[iROF];
285- int orb = (iROF * par.getROFLengthInBC (clock) / o2::constants::lhc::LHCMaxBunches) + tfInfo.firstTForbit ;
286- int bc = (iROF * par.getROFLengthInBC (clock) % o2::constants::lhc::LHCMaxBunches) + par.getROFDelayInBC (clock);
287- o2::InteractionRecord ir (bc, orb);
288- rof.setBCData (ir);
289- rof.setROFrame (iROF);
290- rof.setNEntries (0 );
291- rof.setFirstEntry (-1 );
292- }
293- };
294- // we pick whatever is the largest possible number of rofs since there might be tracks/vertices which are beyond
295- // the clock layer
296- int highestROF{0 };
297- for (const auto & trc : tracks) {
298- highestROF = std::max (highestROF, (int )clockLayer.getROF (trc.getTimeStamp ()));
299- }
300- for (const auto & vtx : vertices) {
301- highestROF = std::max (highestROF, (int )clockLayer.getROF (vtx.getTimeStamp ().lower ()));
302- }
303- highestROF = std::max (highestROF, (int )clockLayer.mNROFsTF );
304- allTrackROFs.resize (highestROF);
305- vertROFvec.resize (highestROF);
306- setBCData (allTrackROFs);
307- setBCData (vertROFvec);
308-
309- mTimeFrame ->useMultiplictyMask (); // use multiplicty selection for IR frames
310-
311- std::vector<int > rofEntries (highestROF + 1 , 0 );
312- for (unsigned int iTrk{0 }; iTrk < tracks.size (); ++iTrk) {
313- auto & trc{tracks[iTrk]};
314- trc.setFirstClusterEntry ((int )allClusIdx.size ()); // before adding tracks, create final cluster indices
315- int ncl = trc.getNumberOfClusters (), nclf = 0 ;
316- for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!!
317- auto clid = trc.getClusterIndex (ic);
318- if (clid >= 0 ) {
319- trc.setClusterSize (ic, mTimeFrame ->getClusterSize ((mDoStaggering ) ? ic : 0 , clid));
320- allClusIdx.push_back (clid);
321- nclf++;
322- }
323- }
324- assert (ncl == nclf);
325- allTracks.emplace_back (trc);
326- auto rof = clockLayer.getROF (trc.getTimeStamp ());
327- ++rofEntries[rof];
328- }
329- std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
330- for (size_t iROF{0 }; iROF < allTrackROFs.size (); ++iROF) {
331- allTrackROFs[iROF].setFirstEntry (rofEntries[iROF]);
332- allTrackROFs[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
333- if (mTimeFrame ->getROFMaskView ().isROFEnabled (clockLayerId, (int )iROF)) {
334- auto & irFrame = irFrames.emplace_back (allTrackROFs[iROF].getBCData (), allTrackROFs[iROF].getBCData () + clockLayer.mROFLength - 1 );
335- irFrame.info = allTrackROFs[iROF].getNEntries ();
336- }
337- }
338- // same thing for vertices rofs
339- std::fill (rofEntries.begin (), rofEntries.end (), 0 );
340- for (const auto & vtx : vertices) {
341- auto rof = clockLayer.getROF (vtx.getTimeStamp ().lower ());
342- ++rofEntries[rof];
343- }
344- std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
345- for (size_t iROF{0 }; iROF < vertROFvec.size (); ++iROF) {
346- vertROFvec[iROF].setFirstEntry (rofEntries[iROF]);
347- vertROFvec[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
291+ auto & tracks = mTimeFrame ->getTracks ();
292+ allTrackLabels.reserve (mTimeFrame ->getTracksLabel ().size ()); // should be 0 if not MC
293+ std::copy (mTimeFrame ->getTracksLabel ().begin (), mTimeFrame ->getTracksLabel ().end (), std::back_inserter (allTrackLabels));
294+ // create the track to clock ROF association here
295+ // the clock ROF is just the fastest ROF
296+ // the number of ROFs does not necessarily reflect the actual ROFs
297+ // due to possible delay of other layers, however it is guaranteed to be >=0
298+ // tracks are guaranteed to be sorted here by their lower edge
299+ // we pick whatever is the largest possible number of rofs since there might be tracks/vertices which are beyond
300+ // the clock layer
301+ int highestROF{0 };
302+ for (const auto & trc : tracks) {
303+ highestROF = std::max (highestROF, (int )clockLayer.getROF (trc.getTimeStamp ()));
304+ }
305+ for (const auto & vtx : vertices) {
306+ highestROF = std::max (highestROF, (int )clockLayer.getROF (vtx.getTimeStamp ().lower ()));
307+ }
308+ highestROF = std::max (highestROF, (int )clockLayer.mNROFsTF );
309+ allTrackROFs.resize (highestROF);
310+ vertROFvec.resize (highestROF);
311+ setBCData (allTrackROFs);
312+ setBCData (vertROFvec);
313+
314+ mTimeFrame ->useMultiplictyMask (); // use multiplicty selection for IR frames
315+
316+ std::vector<int > rofEntries (highestROF + 1 , 0 );
317+ for (unsigned int iTrk{0 }; iTrk < tracks.size (); ++iTrk) {
318+ auto & trc{tracks[iTrk]};
319+ trc.setFirstClusterEntry ((int )allClusIdx.size ()); // before adding tracks, create final cluster indices
320+ int ncl = trc.getNumberOfClusters (), nclf = 0 ;
321+ for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!!
322+ auto clid = trc.getClusterIndex (ic);
323+ if (clid >= 0 ) {
324+ trc.setClusterSize (ic, mTimeFrame ->getClusterSize ((mDoStaggering ) ? ic : 0 , clid));
325+ allClusIdx.push_back (clid);
326+ nclf++;
348327 }
349328 }
329+ assert (ncl == nclf);
330+ allTracks.emplace_back (trc);
331+ auto rof = clockLayer.getROF (trc.getTimeStamp ());
332+ ++rofEntries[rof];
333+ }
334+ std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
335+ for (size_t iROF{0 }; iROF < allTrackROFs.size (); ++iROF) {
336+ allTrackROFs[iROF].setFirstEntry (rofEntries[iROF]);
337+ allTrackROFs[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
338+ if (mTimeFrame ->getROFMaskView ().isROFEnabled (clockLayerId, (int )iROF)) {
339+ auto & irFrame = irFrames.emplace_back (allTrackROFs[iROF].getBCData (), allTrackROFs[iROF].getBCData () + clockLayer.mROFLength - 1 );
340+ irFrame.info = allTrackROFs[iROF].getNEntries ();
341+ }
342+ }
343+ // same thing for vertices rofs
344+ std::fill (rofEntries.begin (), rofEntries.end (), 0 );
345+ for (const auto & vtx : vertices) {
346+ auto rof = clockLayer.getROF (vtx.getTimeStamp ().lower ());
347+ ++rofEntries[rof];
348+ }
349+ std::exclusive_scan (rofEntries.begin (), rofEntries.end (), rofEntries.begin (), 0 );
350+ for (size_t iROF{0 }; iROF < vertROFvec.size (); ++iROF) {
351+ vertROFvec[iROF].setFirstEntry (rofEntries[iROF]);
352+ vertROFvec[iROF].setNEntries (rofEntries[iROF + 1 ] - rofEntries[iROF]);
350353 }
351354
352355 LOGP (info, " ITSTracker pushed {} tracks in {} rofs and {} vertices {}" , allTracks.size (), allTrackROFs.size (), vertices.size (), ((mDoStaggering ) ? " in staggered-readout mode" : " in normal mode" ));
0 commit comments