@@ -127,7 +127,8 @@ struct HStrangeCorrelation {
127127 Configurable<bool > doGenEventSelection{" doGenEventSelection" , true , " use event selections when performing closure test for the gen events" };
128128 Configurable<bool > doClosureTestPureMC{" doClosureTestPureMC" , false , " fill regular ClosureTest histograms without event or reconstructed-trigger selection, using MC vertex z and centrality 0.05; keep truth-particle selections" };
129129 Configurable<bool > selectINELgtZERO{" selectINELgtZERO" , true , " select INEL>0 events" };
130- Configurable<bool > selectINELgtONE{" selectINELgtONE" , false , " select INEL>1 events (at least 2 charged particles in |eta| < 1)" };
130+ Configurable<bool > selectINELgtN{" selectINELgtN" , false , " select INEL>N events (more than N charged particles in |eta| < 1), N = inelGtNThreshold" };
131+ Configurable<int > inelGtNThreshold{" inelGtNThreshold" , 1 , " N of the INEL>N selection (reco: PV contributors, gen: charged physical primaries, both in |eta| < 1)" };
131132 Configurable<float > zVertexCut{" zVertexCut" , 10 , " Cut on PV position" };
132133 Configurable<bool > requireAllGoodITSLayers{" requireAllGoodITSLayers" , false , " require that in the event all ITS are good" };
133134 Configurable<bool > rejectSameBunchPileup{" rejectSameBunchPileup" , false , " reject collisions associated with the same found-by-T0 bunch crossing" };
@@ -3266,6 +3267,37 @@ struct HStrangeCorrelation {
32663267 }
32673268 }
32683269
3270+ // INEL>N at reconstructed level: more than N PV contributors in |eta| < 1.
3271+ // multNTracksPVeta1 is exactly this count (filled by multcenttable), so this is
3272+ // collision.isInelGt0() / isInelGt1() with a free N and needs no track table
3273+ template <typename TCollision>
3274+ bool isInelGtNReco (TCollision const & collision, int threshold)
3275+ {
3276+ return collision.multNTracksPVeta1 () > threshold;
3277+ }
3278+
3279+ // INEL>N at generated level: more than N charged physical primaries in |eta| < 1,
3280+ // counted the same way as multcenttable fills multMCNParticlesEta10
3281+ template <typename TMcParticles>
3282+ bool isInelGtNGen (TMcParticles const & mcParticles, int threshold)
3283+ {
3284+ constexpr double ChargeTolerance = 1e-3 ; // |charge| below this counts as neutral
3285+ int nChEta1 = 0 ;
3286+ for (auto const & mcParticle : mcParticles) {
3287+ if (!mcParticle.isPhysicalPrimary ()) {
3288+ continue ;
3289+ }
3290+ auto const * pdgParticle = pdgDB->GetParticle (mcParticle.pdgCode ());
3291+ if (pdgParticle == nullptr || std::abs (pdgParticle->Charge ()) < ChargeTolerance) {
3292+ continue ;
3293+ }
3294+ if (std::abs (mcParticle.eta ()) < 1 .0f ) {
3295+ ++nChEta1;
3296+ }
3297+ }
3298+ return nChEta1 > threshold;
3299+ }
3300+
32693301 // this function allows for all event selections to be done in a modular way
32703302 template <typename TCollision>
32713303 bool isCollisionSelected (TCollision const & collision)
@@ -3288,7 +3320,7 @@ struct HStrangeCorrelation {
32883320 if (!collision.isInelGt0 () && masterConfigurations.selectINELgtZERO ) {
32893321 return false ;
32903322 }
3291- if (!collision. isInelGt1 ( ) && masterConfigurations.selectINELgtONE ) {
3323+ if (!isInelGtNReco ( collision, masterConfigurations. inelGtNThreshold ) && masterConfigurations.selectINELgtN ) {
32923324 return false ;
32933325 }
32943326 if (!collision.selection_bit (aod::evsel::kIsGoodITSLayersAll ) && masterConfigurations.requireAllGoodITSLayers ) {
@@ -4262,7 +4294,7 @@ struct HStrangeCorrelation {
42624294 float bestCollisionVtxZ = 0 .0f ;
42634295 bool bestCollisionSel8 = false ;
42644296 bool bestCollisionINELgtZERO = false ;
4265- bool bestCollisionINELgtONE = false ;
4297+ bool bestCollisionINELgtN = false ;
42664298 bool bestCollisionNoSameBunchPileup = false ;
42674299 bool bestCollisionGoodTriggerTVX = false ;
42684300 bool bestCollisionGoodZvtxFT0vsPV = false ;
@@ -4281,7 +4313,7 @@ struct HStrangeCorrelation {
42814313 bestCollisionSel8 = collision.sel8 ();
42824314 bestCollisionVtxZ = collision.posZ ();
42834315 bestCollisionINELgtZERO = collision.isInelGt0 ();
4284- bestCollisionINELgtONE = collision. isInelGt1 ( );
4316+ bestCollisionINELgtN = isInelGtNReco ( collision, masterConfigurations. inelGtNThreshold );
42854317 bestCollisionNoSameBunchPileup = collision.selection_bit (o2::aod::evsel::kNoSameBunchPileup );
42864318 bestCollisionGoodTriggerTVX = collision.selection_bit (aod::evsel::kIsTriggerTVX );
42874319 bestCollisionGoodZvtxFT0vsPV = collision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV );
@@ -4333,7 +4365,7 @@ struct HStrangeCorrelation {
43334365 if (!bestCollisionINELgtZERO) {
43344366 return ;
43354367 }
4336- if (masterConfigurations.selectINELgtONE && !bestCollisionINELgtONE ) {
4368+ if (masterConfigurations.selectINELgtN && !bestCollisionINELgtN ) {
43374369 return ;
43384370 }
43394371 if (masterConfigurations.rejectSameBunchPileup && !bestCollisionNoSameBunchPileup) {
@@ -4472,9 +4504,9 @@ struct HStrangeCorrelation {
44724504 {
44734505 // Part 3: a self-contained generator-level study. It deliberately touches no
44744506 // reconstructed quantity in its event selection or in any of its axes: the
4475- // event is selected on generated INEL>0 and the generated vertex only, the
4476- // multiplicity is counted from generated particles, and every object is
4477- // filled with generated coordinates.
4507+ // event is selected on generated INEL>0 (INEL>N if enabled) and the generated
4508+ // vertex only, the multiplicity is counted from generated particles, and every
4509+ // object is filled with generated coordinates.
44784510 //
44794511 // Reconstruction enters in exactly one place -- whether a generated object
44804512 // has a reconstructed counterpart at all -- and that splits the very same
@@ -4495,9 +4527,9 @@ struct HStrangeCorrelation {
44954527 histos.fill (HIST (" PairLossK0/GenStudy/hEventCounter" ), 0 .0f );
44964528
44974529 // Generated-level event selection. No reconstructed variable is used.
4498- // INEL>1 implies INEL>0, so only the tighter enabled selection has to be evaluated
4499- if (masterConfigurations.selectINELgtONE ) {
4500- if (!o2::pwglf::isINELgt1mc (mcParticles, pdgDB )) {
4530+ // INEL>N (N >= 0) implies INEL>0, so only the tighter enabled selection has to be evaluated
4531+ if (masterConfigurations.selectINELgtN ) {
4532+ if (!isInelGtNGen (mcParticles, masterConfigurations. inelGtNThreshold )) {
45014533 return ;
45024534 }
45034535 } else if (masterConfigurations.selectINELgtZERO ) {
@@ -4788,7 +4820,7 @@ struct HStrangeCorrelation {
47884820 float genBestCollisionVtxZ = 0 .0f ;
47894821 bool genBestCollisionSel8 = false ;
47904822 bool genBestCollisionINELgtZERO = false ;
4791- bool genBestCollisionINELgtONE = false ;
4823+ bool genBestCollisionINELgtN = false ;
47924824 bool genBestCollisionNoSameBunchPileup = false ;
47934825 bool genBestCollisionGoodTriggerTVX = false ;
47944826 bool genBestCollisionGoodZvtxFT0vsPV = false ;
@@ -4808,7 +4840,7 @@ struct HStrangeCorrelation {
48084840 genBestCollisionSel8 = recCollision.sel8 ();
48094841 genBestCollisionVtxZ = recCollision.posZ ();
48104842 genBestCollisionINELgtZERO = recCollision.isInelGt0 ();
4811- genBestCollisionINELgtONE = recCollision. isInelGt1 ( );
4843+ genBestCollisionINELgtN = isInelGtNReco ( recCollision, masterConfigurations. inelGtNThreshold );
48124844 genBestCollisionNoSameBunchPileup = recCollision.selection_bit (o2::aod::evsel::kNoSameBunchPileup );
48134845 genBestCollisionGoodTriggerTVX = recCollision.selection_bit (aod::evsel::kIsTriggerTVX );
48144846 genBestCollisionGoodZvtxFT0vsPV = recCollision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV );
@@ -4822,7 +4854,7 @@ struct HStrangeCorrelation {
48224854 genEventSelected = genEventSelected && genCollisionSelected;
48234855 } else if (masterConfigurations.doGenEventSelection ) {
48244856 genEventSelected = genEventSelected && genBestCollisionSel8 && std::abs (genBestCollisionVtxZ) <= masterConfigurations.zVertexCut &&
4825- genBestCollisionINELgtZERO && (!masterConfigurations.selectINELgtONE || genBestCollisionINELgtONE ) &&
4857+ genBestCollisionINELgtZERO && (!masterConfigurations.selectINELgtN || genBestCollisionINELgtN ) &&
48264858 (!masterConfigurations.rejectSameBunchPileup || genBestCollisionNoSameBunchPileup) &&
48274859 (!masterConfigurations.requireGoodTriggerTVX || genBestCollisionGoodTriggerTVX) &&
48284860 (!masterConfigurations.requireGoodZvtxFT0vsPV || genBestCollisionGoodZvtxFT0vsPV) &&
@@ -6192,7 +6224,7 @@ struct HStrangeCorrelation {
61926224 } else {
61936225 bool bestCollisionSel8 = false ;
61946226 bool bestCollisionINELgtZERO = false ;
6195- bool bestCollisionINELgtONE = false ;
6227+ bool bestCollisionINELgtN = false ;
61966228 bool bestCollisionNoSameBunchPileup = false ;
61976229 bool bestCollisionGoodTriggerTVX = false ;
61986230 bool bestCollisionGoodZvtxFT0vsPV = false ;
@@ -6212,7 +6244,7 @@ struct HStrangeCorrelation {
62126244 } else {
62136245 bestCollisionSel8 = recCollision.sel8 ();
62146246 bestCollisionINELgtZERO = recCollision.isInelGt0 ();
6215- bestCollisionINELgtONE = recCollision. isInelGt1 ( );
6247+ bestCollisionINELgtN = isInelGtNReco ( recCollision, masterConfigurations. inelGtNThreshold );
62166248 bestCollisionNoSameBunchPileup = recCollision.selection_bit (o2::aod::evsel::kNoSameBunchPileup );
62176249 bestCollisionGoodTriggerTVX = recCollision.selection_bit (aod::evsel::kIsTriggerTVX );
62186250 bestCollisionGoodZvtxFT0vsPV = recCollision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV );
@@ -6243,7 +6275,7 @@ struct HStrangeCorrelation {
62436275 if (!bestCollisionINELgtZERO) {
62446276 return ;
62456277 }
6246- if (masterConfigurations.selectINELgtONE && !bestCollisionINELgtONE ) {
6278+ if (masterConfigurations.selectINELgtN && !bestCollisionINELgtN ) {
62476279 return ;
62486280 }
62496281 if (masterConfigurations.rejectSameBunchPileup && !bestCollisionNoSameBunchPileup) {
@@ -6587,9 +6619,9 @@ struct HStrangeCorrelation {
65876619 float multEta08 = -1 ;
65886620 float multEta05 = -1 ;
65896621 histos.fill (HIST (" Prediction/hEventSelection" ), 0.5 );
6590- // INEL>1 implies INEL>0, so only the tighter enabled selection has to be evaluated
6591- if (masterConfigurations.selectINELgtONE ) {
6592- if (!o2::pwglf::isINELgt1mc (mcParticles, pdgDB )) {
6622+ // INEL>N (N >= 0) implies INEL>0, so only the tighter enabled selection has to be evaluated
6623+ if (masterConfigurations.selectINELgtN ) {
6624+ if (!isInelGtNGen (mcParticles, masterConfigurations. inelGtNThreshold )) {
65936625 return ;
65946626 }
65956627 } else if (masterConfigurations.selectINELgtZERO ) {
0 commit comments