@@ -531,7 +531,6 @@ struct lambdaspincorrderived {
531531 const ROOT::Math::PtEtaPhiMVector& daughpart1, const ROOT::Math::PtEtaPhiMVector& daughpart2,
532532 int datatype, float mixpairweight, int mixedLeg)
533533 {
534-
535534 auto lambda1Mass = 0.0 ;
536535 auto lambda2Mass = 0.0 ;
537536 if (!usePDGM) {
@@ -622,35 +621,29 @@ struct lambdaspincorrderived {
622621 double epsWeightMixedLeg = 1.0 ;
623622 if (useweight && datatype == 1 ) { // only for ME
624623 if (mixedLeg == 1 ) {
625- // Only leg 1 is from the mixing pool
626624 double w1 = 1.0 ;
627- if (tag1 == 0 ) { // Λ
628- if (hweight1) {
629- w1 = hweight1->GetBinContent (hweight1->FindBin (dphi1, deta1, pt1));
630- }
631- } else { // Λbar
632- if (hweight4) {
633- w1 = hweight4->GetBinContent (hweight4->FindBin (dphi1, deta1, pt1));
634- }
635- }
636- if (w1 > 0.0 && std::isfinite (w1)) {
637- epsWeightMixedLeg = w1;
625+ if (tag1 == 0 && tag2 == 0 ) {
626+ w1 = hweight1->GetBinContent (hweight1->FindBin (dphi1, deta1, pt1));
627+ } else if (tag1 == 0 && tag2 == 1 ) {
628+ w1 = hweight2->GetBinContent (hweight2->FindBin (dphi1, deta1, pt1));
629+ } else if (tag1 == 1 && tag2 == 0 ) {
630+ w1 = hweight3->GetBinContent (hweight3->FindBin (dphi1, deta1, pt1));
631+ } else if (tag1 == 1 && tag2 == 1 ) {
632+ w1 = hweight4->GetBinContent (hweight4->FindBin (dphi1, deta1, pt1));
638633 }
634+ epsWeightMixedLeg = w1;
639635 } else if (mixedLeg == 2 ) {
640- // Only leg 2 is from the mixing pool
641636 double w2 = 1.0 ;
642- if (tag2 == 0 ) { // Λ
643- if (hweight12) {
644- w2 = hweight12->GetBinContent (hweight12->FindBin (dphi2, deta2, pt2));
645- }
646- } else { // Λbar
647- if (hweight42) {
648- w2 = hweight42->GetBinContent (hweight42->FindBin (dphi2, deta2, pt2));
649- }
650- }
651- if (w2 > 0.0 && std::isfinite (w2)) {
652- epsWeightMixedLeg = w2;
637+ if (tag1 == 0 && tag2 == 0 ) {
638+ w2 = hweight12->GetBinContent (hweight12->FindBin (dphi2, deta1, pt2));
639+ } else if (tag1 == 0 && tag2 == 1 ) {
640+ w2 = hweight22->GetBinContent (hweight22->FindBin (dphi2, deta1, pt2));
641+ } else if (tag1 == 1 && tag2 == 0 ) {
642+ w2 = hweight32->GetBinContent (hweight32->FindBin (dphi2, deta1, pt2));
643+ } else if (tag1 == 1 && tag2 == 1 ) {
644+ w2 = hweight42->GetBinContent (hweight42->FindBin (dphi2, deta2, pt2));
653645 }
646+ epsWeightMixedLeg = w2;
654647 }
655648 }
656649
@@ -697,46 +690,55 @@ struct lambdaspincorrderived {
697690 } else if (datatype == 1 ) {
698691 double weight = mixpairweight;
699692 if (useweight) {
700- if (usebothweight) {
701- weight = mixpairweight / (epsWeightMixedLeg);
702- } else {
703- weight = mixpairweight / (epsWeightMixedLeg);
704- }
693+ weight = mixpairweight / (epsWeightMixedLeg);
705694 }
706695 if (weight <= 0.0 ) {
707696 weight = 1.0 ;
708697 }
698+ // LOGF(info, Form("Getting alignment offsets from the CCDB...%2.2f",epsWeightMixedLeg));
709699 histos.fill (HIST (" hPtYMix" ), particle1.Pt (), particle1.Rapidity (), weight);
710700 if (tag1 == 0 && tag2 == 0 ) {
711- histos.fill (HIST (" ME_LL" ), dphi1, deta1, pt1, mixpairweight);
712- histos.fill (HIST (" ME_LL2" ), dphi2, deta2, pt2, mixpairweight);
701+ if (mixedLeg == 1 ) {
702+ histos.fill (HIST (" ME_LL" ), dphi1, deta1, pt1, weight);
703+ } else if (mixedLeg == 2 ) {
704+ histos.fill (HIST (" ME_LL2" ), dphi2, deta2, pt2, weight);
705+ }
713706 histos.fill (HIST (" hSparseLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaR, weight);
714707 if (useAdditionalHisto) {
715708 histos.fill (HIST (" hSparseRapLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaRap, weight);
716709 histos.fill (HIST (" hSparsePhiLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, dphi_pair, weight);
717710 histos.fill (HIST (" hSparsePairMassLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, pairDummy.M (), weight);
718711 }
719712 } else if (tag1 == 0 && tag2 == 1 ) {
720- histos.fill (HIST (" ME_LAL" ), dphi1, deta1, pt1, mixpairweight);
721- histos.fill (HIST (" ME_LAL2" ), dphi2, deta2, pt2, mixpairweight);
713+ if (mixedLeg == 1 ) {
714+ histos.fill (HIST (" ME_LAL" ), dphi1, deta1, pt1, weight);
715+ } else if (mixedLeg == 2 ) {
716+ histos.fill (HIST (" ME_LAL2" ), dphi2, deta2, pt2, weight);
717+ }
722718 histos.fill (HIST (" hSparseLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaR, weight);
723719 if (useAdditionalHisto) {
724720 histos.fill (HIST (" hSparseRapLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaRap, weight);
725721 histos.fill (HIST (" hSparsePhiLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, dphi_pair, weight);
726722 histos.fill (HIST (" hSparsePairMassLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, pairDummy.M (), weight);
727723 }
728724 } else if (tag1 == 1 && tag2 == 0 ) {
729- histos.fill (HIST (" ME_ALL" ), dphi1, deta1, pt1, mixpairweight);
730- histos.fill (HIST (" ME_ALL2" ), dphi2, deta2, pt2, mixpairweight);
725+ if (mixedLeg == 1 ) {
726+ histos.fill (HIST (" ME_ALL" ), dphi1, deta1, pt1, weight);
727+ } else if (mixedLeg == 2 ) {
728+ histos.fill (HIST (" ME_ALL2" ), dphi2, deta2, pt2, weight);
729+ }
731730 histos.fill (HIST (" hSparseAntiLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaR, weight);
732731 if (useAdditionalHisto) {
733732 histos.fill (HIST (" hSparseRapAntiLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaRap, weight);
734733 histos.fill (HIST (" hSparsePhiAntiLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, dphi_pair, weight);
735734 histos.fill (HIST (" hSparsePairMassAntiLambdaLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, pairDummy.M (), weight);
736735 }
737736 } else if (tag1 == 1 && tag2 == 1 ) {
738- histos.fill (HIST (" ME_ALAL" ), dphi1, deta1, pt1, mixpairweight);
739- histos.fill (HIST (" ME_ALAL2" ), dphi2, deta2, pt2, mixpairweight);
737+ if (mixedLeg == 1 ) {
738+ histos.fill (HIST (" ME_ALAL" ), dphi1, deta1, pt1, weight);
739+ } else if (mixedLeg == 2 ) {
740+ histos.fill (HIST (" ME_ALAL2" ), dphi2, deta2, pt2, weight);
741+ }
740742 histos.fill (HIST (" hSparseAntiLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaR, weight);
741743 if (useAdditionalHisto) {
742744 histos.fill (HIST (" hSparseRapAntiLambdaAntiLambdaMixed" ), particle1.M (), particle2.M (), cosThetaDiff, deltaRap, weight);
@@ -1064,17 +1066,17 @@ struct lambdaspincorrderived {
10641066 }
10651067 PROCESS_SWITCH (lambdaspincorrderived, processMEV3, " Process data ME (first-leg, pair-3D maps)" , false );
10661068
1069+ // ---------------------- minimal helpers you already use ----------------------
10671070 static constexpr int N_STATUS = 2 ; // v0Status ∈ {0,1}
10681071
10691072 struct MixBinner {
1070- // constructed from the task's configurables; φ is assumed already constrained into [0, 2π)
10711073 float ptMin, ptMax, ptStep;
10721074 float etaMin, etaMax, etaStep;
10731075 float phiMin, phiMax, phiStep;
10741076
1075- // Mass binning: [1.09, 1.14) with 50 bins (1e-3 GeV/c^2)
1077+ // if you want 1 mass bin (effectively “on/off”), keep nM_=1
10761078 static constexpr float mMin = 1 .09f ;
1077- static constexpr float mMax = 1 .14f ; // exclusive
1079+ static constexpr float mMax = 1 .14f ;
10781080 static constexpr int nM_ = 1 ;
10791081 static constexpr float mStep = (mMax - mMin ) / nM_;
10801082
@@ -1088,7 +1090,6 @@ struct lambdaspincorrderived {
10881090 ptStep = (ptStep > 0 .f ? ptStep : 0 .1f );
10891091 etaStep = (etaStep > 0 .f ? etaStep : 0 .1f );
10901092 phiStep = (phiStep > 0 .f ? phiStep : 0 .1f );
1091-
10921093 nPt_ = std::max (1 , static_cast <int >(std::floor ((ptMax - ptMin) / ptStep + 0 .5f )));
10931094 nEta_ = std::max (1 , static_cast <int >(std::floor ((etaMax - etaMin) / etaStep + 0 .5f )));
10941095 nPhi_ = std::max (1 , static_cast <int >(std::ceil ((phiMax - phiMin) / phiStep)));
@@ -1108,19 +1109,18 @@ struct lambdaspincorrderived {
11081109 if (b < 0 )
11091110 return -1 ;
11101111 if (b >= nBins)
1111- b = nBins - 1 ; // clamp exact-top edge
1112+ b = nBins - 1 ;
11121113 return b;
11131114 }
1114-
11151115 inline int ptBin (float pt) const { return binFromValue (pt, ptMin, ptStep, nPt_); }
1116- inline int etaBin (float eta ) const { return binFromValue (eta , etaMin, etaStep, nEta_); }
1117- inline int phiBin (float phi ) const { return binFromValue (phi , phiMin, phiStep, nPhi_); } // φ already constrained upstream
1116+ inline int etaBin (float e ) const { return binFromValue (e , etaMin, etaStep, nEta_); }
1117+ inline int phiBin (float ph ) const { return binFromValue (ph , phiMin, phiStep, nPhi_); }
11181118 inline int massBin (float m) const { return binFromValue (m, mMin , mStep , nM_); }
11191119 };
11201120
11211121 struct BufferCand {
1122- int64_t collisionIdx; // from col.index()
1123- int64_t rowIndex; // global row id in V0s
1122+ int64_t collisionIdx;
1123+ int64_t rowIndex;
11241124 uint8_t v0Status;
11251125 uint16_t ptBin, etaBin, phiBin, mBin ;
11261126 };
@@ -1130,16 +1130,16 @@ struct lambdaspincorrderived {
11301130 int64_t rowIndex;
11311131 };
11321132
1133- // 6D key: (colBin, status, pt, eta, phi, mass)
11341133 static inline size_t linearKey (int colBin, int statBin,
11351134 int ptBin, int etaBin, int phiBin, int mBin ,
11361135 int nStatus, int nPt, int nEta, int nPhi, int nM)
11371136 {
11381137 return ((((((static_cast <size_t >(colBin) * nStatus + statBin) * nPt + ptBin) * nEta + etaBin) * nPhi + phiBin) * nM + mBin ));
11391138 }
1139+
1140+ // ================================ processMEV4 ================================
11401141 void processMEV4 (EventCandidates const & collisions, AllTrackCandidates const & V0s)
11411142 {
1142- // Build binner from your existing configurables
11431143 MixBinner mb{
11441144 ptMin.value , ptMax.value , ptMix.value , // pT range & step
11451145 v0eta.value , etaMix.value , // |eta| max & step
@@ -1156,9 +1156,7 @@ struct lambdaspincorrderived {
11561156 const size_t nKeys = static_cast <size_t >(nCol) * nStat * nPt * nEta * nPhi * nM;
11571157 std::vector<std::vector<BufferCand>> buffer (nKeys);
11581158
1159- // =========================
1160- // PASS 1: fill 6D buffer
1161- // =========================
1159+ // ---------------- PASS 1: fill the 6D buffer ----------------
11621160 for (auto const & col : collisions) {
11631161 const int colBin = colBinning.getBin (std::make_tuple (col.posz (), col.cent ()));
11641162 auto slice = V0s.sliceBy (tracksPerCollisionV0, col.index ());
@@ -1178,9 +1176,7 @@ struct lambdaspincorrderived {
11781176 if (ptB < 0 || etaB < 0 || phiB < 0 || mB < 0 )
11791177 continue ;
11801178
1181- const size_t key = linearKey (colBin, status, ptB, etaB, phiB, mB ,
1182- nStat, nPt, nEta, nPhi, nM);
1183-
1179+ const size_t key = linearKey (colBin, status, ptB, etaB, phiB, mB , nStat, nPt, nEta, nPhi, nM);
11841180 buffer[key].push_back (BufferCand{
11851181 .collisionIdx = static_cast <int64_t >(col.index ()),
11861182 .rowIndex = static_cast <int64_t >(t.globalIndex ()),
@@ -1192,7 +1188,7 @@ struct lambdaspincorrderived {
11921188 }
11931189 }
11941190
1195- // Helper: get matches for a given candidate (for mixing one leg)
1191+ // small helper (kept local) to fetch matches for a given candidate from the same 6D bin
11961192 auto makeMatchesFor = [&](auto const & cand,
11971193 int colBinLocal,
11981194 int64_t curColIdx) -> std::vector<MatchRef> {
@@ -1209,33 +1205,21 @@ struct lambdaspincorrderived {
12091205 if (ptB < 0 || etaB < 0 || phiB < 0 || mB < 0 )
12101206 return matches;
12111207
1212- const size_t key = linearKey (colBinLocal, status, ptB, etaB, phiB, mB ,
1213- nStat, nPt, nEta, nPhi, nM);
1208+ const size_t key = linearKey (colBinLocal, status, ptB, etaB, phiB, mB , nStat, nPt, nEta, nPhi, nM);
12141209 auto const & binVec = buffer[key];
12151210 if (binVec.empty ())
12161211 return matches;
12171212
12181213 matches.reserve (binVec.size ());
12191214 for (const auto & bc : binVec) {
12201215 if (bc.collisionIdx == curColIdx)
1221- continue ; // ensure different event
1216+ continue ; // different event
12221217 matches.push_back (MatchRef{bc.collisionIdx , bc.rowIndex });
12231218 }
1224-
1225- // Optionally cap number of matches by nEvtMixing
1226- const int cap = nEvtMixing.value ;
1227- const int n = static_cast <int >(matches.size ());
1228- if (cap > 0 && n > cap) {
1229- std::shuffle (matches.begin (), matches.end (), rng);
1230- matches.resize (cap);
1231- }
1232-
12331219 return matches;
12341220 };
12351221
1236- // =========================
1237- // PASS 2: mixing over SE pairs (mix both legs)
1238- // =========================
1222+ // ---------------- PASS 2: loop over SE pairs and mix both legs ----------------
12391223 for (auto const & collision1 : collisions) {
12401224 const int colBin = colBinning.getBin (std::make_tuple (collision1.posz (), collision1.cent ()));
12411225 auto poolA = V0s.sliceBy (tracksPerCollisionV0, collision1.index ());
@@ -1259,20 +1243,38 @@ struct lambdaspincorrderived {
12591243 if (t1.pionIndex () == t2.protonIndex ())
12601244 continue ;
12611245
1262- // matches for replacing leg 1 and leg 2
1263- auto matches1 = makeMatchesFor (t1, colBin, curColId); // t1 -> tX
1264- auto matches2 = makeMatchesFor (t2, colBin, curColId); // t2 -> tY
1246+ // gather matches for both legs from the same 6D bin
1247+ auto matches1 = makeMatchesFor (t1, colBin, curColId); // candidates to replace leg-1
1248+ auto matches2 = makeMatchesFor (t2, colBin, curColId); // candidates to replace leg-2
12651249
1266- const int n1 = static_cast <int >(matches1.size ());
1267- const int n2 = static_cast <int >(matches2.size ());
1268- if (n1 == 0 && n2 == 0 )
1250+ const int n1Eff = static_cast <int >(matches1.size ());
1251+ const int n2Eff = static_cast <int >(matches2.size ());
1252+ if (n1Eff == 0 && n2Eff == 0 )
12691253 continue ;
12701254
1271- // Split "unit" weight between the two modes
1272- const float w1 = (n1 > 0 ? 0 .5f / static_cast <float >(n1) : 0 .f );
1273- const float w2 = (n2 > 0 ? 0 .5f / static_cast <float >(n2) : 0 .f );
1255+ // per-leg depth (configurable)
1256+ int depth = nEvtMixing.value ;
1257+ if (depth <= 0 )
1258+ depth = 1 ;
1259+
1260+ const int n1Take = std::min (depth, n1Eff);
1261+ const int n2Take = std::min (depth, n2Eff);
12741262
1275- // --- Type A: replace leg 1 → (tX, t2) ---
1263+ // split unit weight between legs if both have mixes; else single leg gets full
1264+ const float w1 = (n1Take > 0 ? ((n2Take > 0 ? 0 .5f : 1 .0f ) / static_cast <float >(n1Take)) : 0 .0f );
1265+ const float w2 = (n2Take > 0 ? ((n1Take > 0 ? 0 .5f : 1 .0f ) / static_cast <float >(n2Take)) : 0 .0f );
1266+
1267+ // randomize & truncate per-leg matches to requested depth
1268+ if (n1Take > 0 ) {
1269+ std::shuffle (matches1.begin (), matches1.end (), rng);
1270+ matches1.resize (n1Take);
1271+ }
1272+ if (n2Take > 0 ) {
1273+ std::shuffle (matches2.begin (), matches2.end (), rng);
1274+ matches2.resize (n2Take);
1275+ }
1276+
1277+ // --- Type A: replace leg 1 (t1 -> tX), keep t2
12761278 for (const auto & m : matches1) {
12771279 auto tX = V0s.iteratorAt (m.rowIndex );
12781280 if (!selectionV0 (tX))
@@ -1289,10 +1291,13 @@ struct lambdaspincorrderived {
12891291 const float dPhi = std::fabs (RecoDecay::constrainAngle (lambda1.Phi () - lambda2.Phi (), 0 .0F , harmonicDphi));
12901292 histos.fill (HIST (" deltaPhiMix" ), dPhi, w1);
12911293
1292- fillHistograms2 (tX.v0Status (), t2.v0Status (), lambda1, lambda2, proton1, proton2, 1 , w1, 1 );
1294+ // datatype=1 (ME), mixedLeg=1
1295+ fillHistograms2 (tX.v0Status (), t2.v0Status (),
1296+ lambda1, lambda2, proton1, proton2,
1297+ /* datatype=*/ 1 , /* weight=*/ w1, /* mixedLeg=*/ 1 );
12931298 }
12941299
1295- // --- Type B: replace leg 2 → (t1, tY) ---
1300+ // --- Type B: replace leg 2 (t2 -> tY), keep t1
12961301 for (const auto & m : matches2) {
12971302 auto tY = V0s.iteratorAt (m.rowIndex );
12981303 if (!selectionV0 (tY))
@@ -1309,13 +1314,15 @@ struct lambdaspincorrderived {
13091314 const float dPhi = std::fabs (RecoDecay::constrainAngle (lambda1.Phi () - lambda2.Phi (), 0 .0F , harmonicDphi));
13101315 histos.fill (HIST (" deltaPhiMix" ), dPhi, w2);
13111316
1312- fillHistograms2 (t1.v0Status (), tY.v0Status (), lambda1, lambda2, proton1, proton2, 1 , w2, 2 );
1317+ // datatype=1 (ME), mixedLeg=2
1318+ fillHistograms2 (t1.v0Status (), tY.v0Status (),
1319+ lambda1, lambda2, proton1, proton2,
1320+ /* datatype=*/ 1 , /* weight=*/ w2, /* mixedLeg=*/ 2 );
13131321 }
13141322 }
13151323 }
13161324 }
1317-
1318- PROCESS_SWITCH (lambdaspincorrderived, processMEV4, " Process data ME (5d buffer)" , false );
1325+ PROCESS_SWITCH (lambdaspincorrderived, processMEV4, " Process data ME (6D buffer, both legs mixed, depth-capped)" , false );
13191326};
13201327WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
13211328{
0 commit comments