@@ -302,6 +302,13 @@ struct Photonhbt {
302302 Configurable<float > cfgMaxAsymmetry{" cfgMaxAsymmetry" , -1 .f , " max |p_{T, 1} - p_{T, 2}|/(p_{T, 1} + p_{T, 2}) asymmetry cut" };
303303 } ggpaircuts;
304304
305+ struct : ConfigurableGroup {
306+ std::string prefix = " pairsep_group" ;
307+ Configurable<bool > cfgDoPairSepQA{" cfgDoPairSepQA" , true , " fill SE/ME same-sign leg separation histograms" };
308+ Configurable<float > cfgUSigEta{" cfgUSigEta" , 0 .02f , " eta scale defining u (axis units only, NOT a cut)" };
309+ Configurable<float > cfgUSigPhi{" cfgUSigPhi" , 0 .05f , " phi scale defining u (axis units only, NOT a cut)" };
310+ } pairsep;
311+
305312 EMPhotonEventCut fEMEventCut ;
306313 struct : ConfigurableGroup {
307314 std::string prefix = " eventcut_group" ;
@@ -588,6 +595,24 @@ struct Photonhbt {
588595 return o;
589596 }
590597
598+ struct PairSep {
599+ float dEtaPP{0 }, dPhiPP{0 }, dEtaNN{0 }, dPhiNN{0 };
600+ float u{999 .f };
601+ };
602+ PairSep computePairSep (float etaP1, float phiP1, float etaN1, float phiN1,
603+ float etaP2, float phiP2, float etaN2, float phiN2) const
604+ {
605+ PairSep s;
606+ s.dEtaPP = etaP1 - etaP2;
607+ s.dPhiPP = RecoDecay::constrainAngle (phiP1 - phiP2, -o2::constants::math::PI );
608+ s.dEtaNN = etaN1 - etaN2;
609+ s.dPhiNN = RecoDecay::constrainAngle (phiN1 - phiN2, -o2::constants::math::PI );
610+ const float sE = pairsep.cfgUSigEta .value , sP = pairsep.cfgUSigPhi .value ;
611+ s.u = std::min (std::hypot (s.dEtaPP / sE , s.dPhiPP / sP ),
612+ std::hypot (s.dEtaNN / sE , s.dPhiNN / sP ));
613+ return s;
614+ }
615+
591616 struct TruthGamma {
592617 int id = -1 , posId = -1 , negId = -1 ;
593618 float eta = 0 .f, phi = 0 .f, pt = 0 .f;
@@ -644,6 +669,19 @@ struct Photonhbt {
644669 fRegistry .fill (HIST (base) + HIST (" hSparseDeltaRDeltaZQinv" ), obs.deltaR , obs.deltaZ , obs.qinv );
645670 }
646671
672+ static constexpr std::string_view pairsep_types[2 ] = {" PairSep/same/" , " PairSep/mix/" };
673+ template <int ev_id>
674+ inline void fillPairSep (PairSep const & s, PairQAObservables const & obs)
675+ {
676+ if (!pairsep.cfgDoPairSepQA .value || obs.qinv >= 0 .5f )
677+ return ;
678+ fRegistry .fill (HIST (pairsep_types[ev_id]) + HIST (" hDEtaDPhiKt_PP" ), s.dEtaPP , s.dPhiPP , obs.kt );
679+ fRegistry .fill (HIST (pairsep_types[ev_id]) + HIST (" hDEtaDPhiKt_NN" ), s.dEtaNN , s.dPhiNN , obs.kt );
680+ fRegistry .fill (HIST (pairsep_types[ev_id]) + HIST (" hU_Qinv_Kt" ), s.u , obs.qinv , obs.kt );
681+ fRegistry .fill (HIST (pairsep_types[ev_id]) + HIST (" hU_Qinv_dE" ), s.u , obs.qinv ,
682+ std::fabs (obs.v1 .E () - obs.v2 .E ()));
683+ }
684+
647685 template <int ev_id>
648686 inline void fillFullRangeDeltaRCosOA (float qinv, float drOverCosOA)
649687 {
@@ -794,6 +832,17 @@ struct Photonhbt {
794832
795833 fRegistry .addClone (" Pair/same/" , " Pair/mix/" );
796834
835+ for (const std::string sm : {" PairSep/same/" , " PairSep/mix/" }) {
836+ fRegistry .add ((sm + " hDEtaDPhiKt_PP" ).c_str (), " e^{+}e^{+};#Delta#eta;#Delta#phi (rad);k_{T} (GeV/c)" ,
837+ kTHnSparseF , {{160 , -0 .4f , 0 .4f }, {160 , -0 .4f , 0 .4f }, axisKt}, true );
838+ fRegistry .add ((sm + " hDEtaDPhiKt_NN" ).c_str (), " e^{-}e^{-};#Delta#eta;#Delta#phi (rad);k_{T} (GeV/c)" ,
839+ kTHnSparseF , {{160 , -0 .4f , 0 .4f }, {160 , -0 .4f , 0 .4f }, axisKt}, true );
840+ fRegistry .add ((sm + " hU_Qinv_Kt" ).c_str (), " ;u;q_{inv} (GeV/c);k_{T} (GeV/c)" ,
841+ kTHnSparseF , {{100 , 0 .f , 10 .f }, {50 , 0 .f , 0 .5f }, axisKt}, true );
842+ fRegistry .add ((sm + " hU_Qinv_dE" ).c_str (), " ;u;q_{inv} (GeV/c);#DeltaE (GeV)" ,
843+ kTHnSparseF , {{50 , 0 .f , 10 .f }, {50 , 0 .f , 0 .5f }, {40 , 0 .f , 2 .f }}, true );
844+ }
845+
797846 fRegistry .add (" Pair/same/EtaTopology/hSparse_DEtaDPhi_kT_sameSideV0_sameSideLegs" ,
798847 " both V0 same #eta-side, all legs same side;"
799848 " #Delta#eta;#Delta#phi (rad);k_{T} (GeV/c)" ,
@@ -1812,6 +1861,9 @@ struct Photonhbt {
18121861 continue ;
18131862 idsAfterDR.insert (g1.globalIndex ());
18141863 idsAfterDR.insert (g2.globalIndex ());
1864+ fillPairSep<0 >(computePairSep (pos1.eta (), pos1.phi (), ele1.eta (), ele1.phi (),
1865+ pos2.eta (), pos2.phi (), ele2.eta (), ele2.phi ()),
1866+ obs);
18151867 if (doQA)
18161868 fillPairQAStep<0 , 1 >(obs, centForQA, occupancy);
18171869 if (!passRZCut (obs.deltaR , obs.deltaZ ))
@@ -1903,6 +1955,9 @@ struct Photonhbt {
19031955 fRegistry .fill (HIST (" Pair/mix/hDeltaRCosOA" ), obs.drOverCosOA );
19041956 if (obs.drOverCosOA < ggpaircuts.cfgMinDRCosOA )
19051957 continue ;
1958+ fillPairSep<1 >(computePairSep (g1.legEta (0 ), g1.legPhi (0 ), g1.legEta (1 ), g1.legPhi (1 ),
1959+ g2.legEta (0 ), g2.legPhi (0 ), g2.legEta (1 ), g2.legPhi (1 )),
1960+ obs);
19061961 if (doQA)
19071962 fillPairQAStep<1 , 1 >(obs, centForQA, occupancy);
19081963 if (!passRZCut (obs.deltaR , obs.deltaZ ))
0 commit comments