2323#include < Framework/Logger.h>
2424
2525#include < cstdint>
26+ #include < optional>
2627
2728namespace o2 ::analysis::femto
2829{
@@ -308,6 +309,12 @@ void processMixedEvent(T1 const& Collisions,
308309 int windowSizeRaw = 0 ;
309310 int windowSizeEffective = 0 ;
310311
312+ // collision1 is fixed across each mixing window, so its track slice is
313+ // materialized once per window and reused for every mixing partner, instead
314+ // of being re-sliced (a fresh arrow Slice + selection copy, the dominant cost
315+ // on the heaviest femto trains) on every (collision1, collision2) pair.
316+ std::optional<decltype (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle1;
317+
311318 for (auto const & [collision1, collision2] : o2::soa::selfCombinations (policy, depth, -1 , Collisions, Collisions)) {
312319
313320 // --- new window ---
@@ -318,6 +325,7 @@ void processMixedEvent(T1 const& Collisions,
318325 windowSizeRaw = 0 ;
319326 windowSizeEffective = 0 ;
320327 lastCollisionIndex = collision1.globalIndex ();
328+ sliceParticle1.emplace (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache));
321329 }
322330
323331 ++windowSizeRaw;
@@ -329,20 +337,18 @@ void processMixedEvent(T1 const& Collisions,
329337
330338 CprManager.setMagField (collision1.magField ());
331339
332- auto sliceParticle1 = Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache);
333-
334340 auto sliceParticle2 = Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache);
335341
336342 PairHistManager.resetTrackedParticlesPerEvent ();
337343
338- if (sliceParticle1. size () == 0 || sliceParticle2.size () == 0 ) {
344+ if (sliceParticle1-> size () == 0 || sliceParticle2.size () == 0 ) {
339345 PairHistManager.fillMixingQaMePerEvent ();
340346 continue ;
341347 }
342348
343349 bool hasValidPair = false ;
344350 PairHistManager.fillMixingQaMe (collision1, collision2);
345- for (auto const & [p1, p2] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (sliceParticle1, sliceParticle2))) {
351+ for (auto const & [p1, p2] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (* sliceParticle1, sliceParticle2))) {
346352
347353 if (!PcManager.isCleanPair (p1, p2, TrackTable)) {
348354 continue ;
@@ -415,6 +421,12 @@ void processMixedEvent(T1 const& Collisions,
415421 int windowSizeRaw = 0 ;
416422 int windowSizeEffective = 0 ;
417423
424+ // collision1 is fixed across each mixing window, so its track slice is
425+ // materialized once per window and reused for every mixing partner, instead
426+ // of being re-sliced (a fresh arrow Slice + selection copy, the dominant cost
427+ // on the heaviest femto trains) on every (collision1, collision2) pair.
428+ std::optional<decltype (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle1;
429+
418430 for (auto const & [collision1, collision2] : o2::soa::selfCombinations (policy, depth, -1 , Collisions, Collisions)) {
419431 if (collision1.globalIndex () != lastCollisionIndex) {
420432 if (lastCollisionIndex != -1 ) {
@@ -423,6 +435,7 @@ void processMixedEvent(T1 const& Collisions,
423435 windowSizeRaw = 0 ;
424436 windowSizeEffective = 0 ;
425437 lastCollisionIndex = collision1.globalIndex ();
438+ sliceParticle1.emplace (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache));
426439 }
427440
428441 ++windowSizeRaw;
@@ -434,21 +447,19 @@ void processMixedEvent(T1 const& Collisions,
434447
435448 CprManager.setMagField (collision1.magField ());
436449
437- auto sliceParticle1 = Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache);
438-
439450 auto sliceParticle2 = Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache);
440451
441452 PairHistManager.resetTrackedParticlesPerEvent ();
442453
443- if (sliceParticle1. size () == 0 || sliceParticle2.size () == 0 ) {
454+ if (sliceParticle1-> size () == 0 || sliceParticle2.size () == 0 ) {
444455 PairHistManager.fillMixingQaMePerEvent ();
445456 continue ;
446457 }
447458
448459 bool hasValidPair = false ;
449460 PairHistManager.fillMixingQaMe (collision1, collision2);
450461
451- for (auto const & [p1, p2] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (sliceParticle1, sliceParticle2))) {
462+ for (auto const & [p1, p2] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (* sliceParticle1, sliceParticle2))) {
452463
453464 if (!ParticleCleaner1.isClean (p1, mcParticles, mcMothers, mcPartonicMothers) ||
454465 !ParticleCleaner2.isClean (p2, mcParticles, mcMothers, mcPartonicMothers)) {
0 commit comments