@@ -459,20 +459,34 @@ void processMixedEvent(T1 const& Collisions,
459459 T10 & CtrManager,
460460 T11 & TcManager)
461461{
462- int64_t lastCollisionIndex = -1 ;
462+ int64_t lastCollisionIndex1 = -1 ;
463+ int64_t lastCollisionIndex2 = -1 ;
463464 int windowSizeRaw = 0 ;
464465 int windowSizeEffective = 0 ;
465466
467+ // collision1 stays fixed across the outer mixing window, and collision2 stays fixed across each inner sub-window (it only advances once collision3 wraps
468+ // back to its start Both slices are therefore materialized once per window/sub-window and reused, instead of being re-sliced, i.e. a fresh arrow Slice + selection copy
469+ std::optional<decltype (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle1;
470+ std::optional<decltype (Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle2;
471+
466472 for (auto const & [collision1, collision2, collision3] : o2::soa::selfCombinations (policy, depth, -1 , Collisions, Collisions, Collisions)) {
467473
468- // --- new window ---
469- if (collision1.globalIndex () != lastCollisionIndex ) {
470- if (lastCollisionIndex != -1 ) {
474+ // outer window
475+ if (collision1.globalIndex () != lastCollisionIndex1 ) {
476+ if (lastCollisionIndex1 != -1 ) {
471477 TripletHistManager.fillMixingQaMePerMixingBin (windowSizeRaw, windowSizeEffective);
472478 }
473479 windowSizeRaw = 0 ;
474480 windowSizeEffective = 0 ;
475- lastCollisionIndex = collision1.globalIndex ();
481+ lastCollisionIndex1 = collision1.globalIndex ();
482+ lastCollisionIndex2 = -1 ; // force sliceParticle2 to refresh below
483+ sliceParticle1.emplace (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache));
484+ }
485+
486+ // inner sub-window
487+ if (collision2.globalIndex () != lastCollisionIndex2) {
488+ lastCollisionIndex2 = collision2.globalIndex ();
489+ sliceParticle2.emplace (Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache));
476490 }
477491
478492 ++windowSizeRaw;
@@ -486,21 +500,19 @@ void processMixedEvent(T1 const& Collisions,
486500
487501 CtrManager.setMagField (collision1.magField ());
488502
489- auto sliceParticle1 = Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache);
490- auto sliceParticle2 = Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache);
491503 auto sliceParticle3 = Partition3->sliceByCached (o2::aod::femtobase::stored::fColId , collision3.globalIndex (), cache);
492504
493505 TripletHistManager.resetTrackedParticlesPerEvent ();
494506
495- if (sliceParticle1. size () == 0 || sliceParticle2. size () == 0 || sliceParticle3.size () == 0 ) {
507+ if (sliceParticle1-> size () == 0 || sliceParticle2-> size () == 0 || sliceParticle3.size () == 0 ) {
496508 TripletHistManager.fillMixingQaMePerEvent ();
497509 continue ;
498510 }
499511
500512 bool hasValidTriplet = false ;
501513 TripletHistManager.fillMixingQaMe (collision1, collision2, collision3);
502514
503- for (auto const & [p1, p2, p3] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (sliceParticle1, sliceParticle2, sliceParticle3))) {
515+ for (auto const & [p1, p2, p3] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (* sliceParticle1, * sliceParticle2, sliceParticle3))) {
504516 // pair cleaning
505517 if (!TcManager.isCleanTriplet (p1, p2, p3, TrackTable)) {
506518 continue ;
@@ -528,7 +540,7 @@ void processMixedEvent(T1 const& Collisions,
528540 TripletHistManager.fillMixingQaMePerEvent ();
529541 }
530542
531- // --- final window ---
543+ // final window
532544 if (windowSizeRaw > 0 ) {
533545 TripletHistManager.fillMixingQaMePerMixingBin (windowSizeRaw, windowSizeEffective);
534546 }
@@ -563,19 +575,34 @@ void processMixedEvent(T1 const& Collisions,
563575 T12 & CtrManager,
564576 T13 & TcManager)
565577{
566- int64_t lastCollisionIndex = -1 ;
578+ int64_t lastCollisionIndex1 = -1 ;
579+ int64_t lastCollisionIndex2 = -1 ;
567580 int windowSizeRaw = 0 ;
568581 int windowSizeEffective = 0 ;
569582
583+ // collision1 stays fixed across the outer mixing window, and collision2 stays fixed across each inner sub-window (it only advances once collision3 wraps
584+ // back to its start Both slices are therefore materialized once per window/sub-window and reused, instead of being re-sliced, i.e. a fresh arrow Slice + selection copy
585+ std::optional<decltype (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle1;
586+ std::optional<decltype (Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , 0 , cache))> sliceParticle2;
587+
570588 for (auto const & [collision1, collision2, collision3] : o2::soa::selfCombinations (policy, depth, -1 , Collisions, Collisions, Collisions)) {
571589
572- if (collision1.globalIndex () != lastCollisionIndex) {
573- if (lastCollisionIndex != -1 ) {
590+ // outer window
591+ if (collision1.globalIndex () != lastCollisionIndex1) {
592+ if (lastCollisionIndex1 != -1 ) {
574593 TripletHistManager.fillMixingQaMePerMixingBin (windowSizeRaw, windowSizeEffective);
575594 }
576595 windowSizeRaw = 0 ;
577596 windowSizeEffective = 0 ;
578- lastCollisionIndex = collision1.globalIndex ();
597+ lastCollisionIndex1 = collision1.globalIndex ();
598+ lastCollisionIndex2 = -1 ; // force sliceParticle2 to refresh below
599+ sliceParticle1.emplace (Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache));
600+ }
601+
602+ // inner sub-window
603+ if (collision2.globalIndex () != lastCollisionIndex2) {
604+ lastCollisionIndex2 = collision2.globalIndex ();
605+ sliceParticle2.emplace (Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache));
579606 }
580607
581608 ++windowSizeRaw;
@@ -589,21 +616,19 @@ void processMixedEvent(T1 const& Collisions,
589616
590617 CtrManager.setMagField (collision1.magField ());
591618
592- auto sliceParticle1 = Partition1->sliceByCached (o2::aod::femtobase::stored::fColId , collision1.globalIndex (), cache);
593- auto sliceParticle2 = Partition2->sliceByCached (o2::aod::femtobase::stored::fColId , collision2.globalIndex (), cache);
594619 auto sliceParticle3 = Partition3->sliceByCached (o2::aod::femtobase::stored::fColId , collision3.globalIndex (), cache);
595620
596621 TripletHistManager.resetTrackedParticlesPerEvent ();
597622
598- if (sliceParticle1. size () == 0 || sliceParticle2. size () == 0 || sliceParticle3.size () == 0 ) {
623+ if (sliceParticle1-> size () == 0 || sliceParticle2-> size () == 0 || sliceParticle3.size () == 0 ) {
599624 TripletHistManager.fillMixingQaMePerEvent ();
600625 continue ;
601626 }
602627
603628 bool hasValidTriplet = false ;
604629 TripletHistManager.fillMixingQaMe (collision1, collision2, collision3);
605630
606- for (auto const & [p1, p2, p3] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (sliceParticle1, sliceParticle2, sliceParticle3))) {
631+ for (auto const & [p1, p2, p3] : o2::soa::combinations (o2::soa::CombinationsFullIndexPolicy (* sliceParticle1, * sliceParticle2, sliceParticle3))) {
607632 // pair cleaning
608633 if (!TcManager.isCleanTriplet (p1, p2, p3, TrackTable)) {
609634 continue ;
@@ -631,6 +656,7 @@ void processMixedEvent(T1 const& Collisions,
631656 TripletHistManager.fillMixingQaMePerEvent ();
632657 }
633658
659+ // --- final window ---
634660 if (windowSizeRaw > 0 ) {
635661 TripletHistManager.fillMixingQaMePerMixingBin (windowSizeRaw, windowSizeEffective);
636662 }
0 commit comments