@@ -37,17 +37,16 @@ using namespace o2::framework;
3737using namespace o2 ::framework::expressions;
3838using namespace o2 ::soa;
3939using namespace o2 ::aod::hf_sel_electron;
40-
41- // definition of ME variables and new types
4240std::vector<double > zBins{VARIABLE_WIDTH, -10.0 , -2.5 , 2.5 , 10.0 };
4341std::vector<double > multBins{VARIABLE_WIDTH, 0 ., 200 ., 500.0 , 5000 .};
4442std::vector<double > multBinsMcGen{VARIABLE_WIDTH, 0 ., 20 ., 50.0 , 500 .}; // In MCGen multiplicity is defined by counting primaries
4543using BinningType = ColumnBinningPolicy<aod::collision::PosZ, aod::mult::MultFV0M<aod::mult::MultFV0A, aod::mult::MultFV0C>>;
4644BinningType corrBinning{{zBins, multBins}, true };
47-
45+ using BinningTypeMcGen = ColumnBinningPolicy<aod::mccollision::PosZ, o2::aod::mult::MultMCFT0A>;
4846struct HfCorrelatorHfeHadrons {
49- SliceCache cache;
47+
5048 Produces<aod::HfEHadronPair> entryElectronHadronPair;
49+ Produces<aod::HfEHadronMcPair> entryElectronHadronPairmcGen;
5150 // Configurables
5251 // Event Selection
5352 Configurable<float > zPvPosMax{" zPvPosMax" , 10 ., " Maximum z of the primary vertex (cm)" };
@@ -63,29 +62,48 @@ struct HfCorrelatorHfeHadrons {
6362 // Electron hadron correlation condition
6463 Configurable<bool > ptCondition{" ptCondition" , true , " Electron pT should be greater than associate particle pT" };
6564
65+ SliceCache cache;
6666 using TableCollisions = o2::soa::Filtered<o2::soa::Join<aod::Collisions, aod::Mults, aod::EvSels>>;
6767 using TableCollision = TableCollisions::iterator;
6868 using TableTracks = o2::soa::Join<o2::aod::Tracks, o2::aod::TracksCov, o2::aod::TracksExtra, o2::aod::TracksDCA, o2::aod::TrackSelection, o2::aod::TrackSelectionExtension>;
69-
69+ using McGenTableCollisions = soa::Join<aod::McCollisions, aod::MultsExtraMC>;
70+ using McGenTableCollision = McGenTableCollisions::iterator;
7071 using McTableCollisions = o2::soa::Filtered<o2::soa::Join<TableCollisions, aod::McCollisionLabels>>;
7172 using McTableCollision = McTableCollisions::iterator;
7273 using McTableTracks = soa::Join<TableTracks, aod::McTrackLabels>;
7374
74- Filter CollisionFilter = nabs(aod::collision::posZ) < zPvPosMax && aod::collision::numContrib > static_cast <uint16_t >(1 );
75+ Filter collisionFilter = nabs(aod::collision::posZ) < zPvPosMax && aod::collision::numContrib > static_cast <uint16_t >(1 );
7576 Preslice<aod::Tracks> perCol = aod::track::collisionId;
7677 Preslice<aod::HfSelEl> perCollision = aod::hf_sel_electron::collisionId;
7778 HistogramConfigSpec hCorrelSpec{HistType::kTHnSparseD , {{30 , 0 ., 30 .}, {20 , 0 ., 20 .}, {32 , -o2::constants::math::PIHalf, 3 . * o2::constants::math::PIHalf}, {50 , -1.8 , 1.8 }}};
7879
7980 HistogramRegistry registry{
8081 " registry" ,
8182 {{" hInclusiveEHCorrel" , " Sparse for Delta phi and Delta eta Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
83+ {" hLSEHCorrel" , " Sparse for Delta phi and Delta eta Like sign Electron pair with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
84+ {" hULSEHCorrel" , " Sparse for Delta phi and Delta eta UnLike sign Electron pair with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
85+ {" hMCgenNonHfEHCorrel" , " Sparse for Delta phi and Delta eta Non Hf for McGen Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
86+ {" hMCgenInclusiveEHCorrl" , " Sparse for Delta phi and Delta eta for McGen Electron pair with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
8287 {" hptElectron" , " hptElectron" , {HistType::kTH1F , {{100 , 0 , 100 }}}},
83- {" hMixEventInclusiveEHCorrl" , " Sparse for mix event Delta phi and Delta eta Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec}}};
88+
89+ {" hMixEventInclusiveEHCorrl" , " Sparse for mix event Delta phi and Delta eta Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
90+ {" hMixEventLSEHCorrel" , " Sparse for mix event Delta phi and Delta eta Like sign Electron pair with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
91+ {" hMixEventULSEHCorrel" , " Sparse for mix event Delta phi and Delta eta Unlike sign Electron pair with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
92+ {" hMixEventMcGenInclusiveEHCorrl" , " Sparse for mix event Delta phi and Delta eta Mc gen Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec},
93+ {" hMixEventMcGenNonHfEHCorrl" , " Sparse for mix event Delta phi and Delta eta Mc gen Inclusive Electron with Hadron;p_{T}^{e} (GeV#it{/c});p_{T}^{h} (GeV#it{/c});#Delta#varphi;#Delta#eta;" , hCorrelSpec}}};
8494
8595 void init (InitContext&)
8696 {
8797 registry.get <THnSparse>(HIST (" hInclusiveEHCorrel" ))->Sumw2 ();
98+ registry.get <THnSparse>(HIST (" hLSEHCorrel" ))->Sumw2 ();
99+ registry.get <THnSparse>(HIST (" hULSEHCorrel" ))->Sumw2 ();
100+ registry.get <THnSparse>(HIST (" hMCgenInclusiveEHCorrl" ))->Sumw2 ();
101+ registry.get <THnSparse>(HIST (" hMCgenNonHfEHCorrel" ))->Sumw2 ();
88102 registry.get <THnSparse>(HIST (" hMixEventInclusiveEHCorrl" ))->Sumw2 ();
103+ registry.get <THnSparse>(HIST (" hMixEventLSEHCorrel" ))->Sumw2 ();
104+ registry.get <THnSparse>(HIST (" hMixEventULSEHCorrel" ))->Sumw2 ();
105+ registry.get <THnSparse>(HIST (" hMixEventMcGenInclusiveEHCorrl" ))->Sumw2 ();
106+ registry.get <THnSparse>(HIST (" hMixEventMcGenNonHfEHCorrl" ))->Sumw2 ();
89107 }
90108
91109 // Associated Hadron Selection Cut
@@ -132,27 +150,49 @@ struct HfCorrelatorHfeHadrons {
132150 double ptHadron = -999 ;
133151 double etaHadron = -999 ;
134152 double phiHadron = -999 ;
135-
136- if (!eTrack.isEmcal ())
153+ if (!eTrack.isEmcal ()) {
137154 continue ;
138-
155+ }
139156 registry.fill (HIST (" hptElectron" ), ptElectron);
157+
140158 for (const auto & hTrack : tracks) {
141- if (hTrack.globalIndex () == eTrack.trackId ())
159+ if (hTrack.globalIndex () == eTrack.trackId ()) {
142160 continue ;
161+ }
162+
143163 // Apply Hadron cut
144- if (!selAssoHadron (hTrack))
164+ if (!selAssoHadron (hTrack)) {
145165 continue ;
166+ }
167+
146168 ptHadron = hTrack.pt ();
147169 phiHadron = hTrack.phi ();
148170 etaHadron = hTrack.eta ();
149171
150- if (ptCondition && (ptElectron < ptHadron))
172+ if (ptCondition && (ptElectron < ptHadron)) {
151173 continue ;
174+ }
175+
152176 deltaPhi = RecoDecay::constrainAngle (phiElectron - phiHadron, -o2::constants::math::PIHalf);
153177 deltaEta = etaElectron - etaHadron;
154178 registry.fill (HIST (" hInclusiveEHCorrel" ), ptElectron, ptHadron, deltaPhi, deltaEta);
155- entryElectronHadronPair (deltaPhi, deltaEta, ptElectron, ptHadron, poolBin);
179+ int isLSElectroncorr = 0 ;
180+ int isULSElectroncorr = 0 ;
181+ if (eTrack.isLSElectron () > 0 ) {
182+ for (int i = 0 ; i < eTrack.isLSElectron (); ++i) {
183+
184+ registry.fill (HIST (" hLSEHCorrel" ), ptElectron, ptHadron, deltaPhi, deltaEta);
185+ ++isLSElectroncorr;
186+ }
187+ }
188+ if (eTrack.isULSElectron () > 0 ) {
189+ for (int i = 0 ; i < eTrack.isULSElectron (); ++i) {
190+
191+ registry.fill (HIST (" hULSEHCorrel" ), ptElectron, ptHadron, deltaPhi, deltaEta);
192+ ++isULSElectroncorr;
193+ }
194+ }
195+ entryElectronHadronPair (deltaPhi, deltaEta, ptElectron, ptHadron, poolBin, isLSElectroncorr, isULSElectroncorr);
156196 }
157197 }
158198 }
@@ -173,58 +213,139 @@ struct HfCorrelatorHfeHadrons {
173213 double etaHadronMix = -999 ;
174214 double phiHadronMix = -999 ;
175215 int poolBin = corrBinning.getBin (std::make_tuple (c2.posZ (), c2.multFV0M ()));
176- for (auto & [t1, t2] : combinations (CombinationsFullIndexPolicy (tracks1, tracks2))) {
177- if (!t1.isEmcal ())
216+ for (const auto & [t1, t2] : combinations (CombinationsFullIndexPolicy (tracks1, tracks2))) {
217+ if (!t1.isEmcal ()) {
178218 continue ;
219+ }
220+
179221 ptHadronMix = t2.pt ();
180222 ptElectronMix = t1.ptTrack ();
181223 phiElectronMix = t1.phiTrack ();
182224 phiHadronMix = t2.phi ();
183225 etaElectronMix = t1.etaTrack ();
184226 etaHadronMix = t2.eta ();
185- if (!selAssoHadron (t2))
227+ if (!selAssoHadron (t2)) {
186228 continue ;
187- if (ptCondition && (ptElectronMix < ptHadronMix))
229+ }
230+
231+ if (ptCondition && (ptElectronMix < ptHadronMix)) {
188232 continue ;
233+ }
234+
189235 deltaPhiMix = RecoDecay::constrainAngle (phiElectronMix - phiHadronMix, -o2::constants::math::PIHalf);
190236 deltaEtaMix = etaElectronMix - etaHadronMix;
191237
192238 registry.fill (HIST (" hMixEventInclusiveEHCorrl" ), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix);
193- entryElectronHadronPair (deltaPhiMix, deltaEtaMix, ptElectronMix, ptHadronMix, poolBin);
239+ int isLSElectroncorr = 0 ;
240+ int isULSElectroncorr = 0 ;
241+ if (t1.isLSElectron () > 0 ) {
242+ for (int i = 0 ; i < t1.isLSElectron (); ++i) {
243+
244+ registry.fill (HIST (" hMixEventLSEHCorrel" ), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix);
245+ ++isLSElectroncorr;
246+ }
247+ }
248+ if (t1.isULSElectron () > 0 ) {
249+ for (int i = 0 ; i < t1.isULSElectron (); ++i) {
250+
251+ registry.fill (HIST (" hMixEventULSEHCorrel" ), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix);
252+ ++isULSElectroncorr;
253+ }
254+ }
255+ entryElectronHadronPair (deltaPhiMix, deltaEtaMix, ptElectronMix, ptHadronMix, poolBin, isLSElectroncorr, isULSElectroncorr);
194256 }
195257 }
196258
197259 // ======= Process starts for Data, Same event ============
198260
199261 void processData (TableCollision const & collision,
200- aod::HfSelEl const & electron,
262+ aod::HfCorrSelEl const & electron,
201263 TableTracks const & tracks)
202264 {
203265 fillCorrelation (collision, electron, tracks);
204266 }
205267
206- PROCESS_SWITCH (HfCorrelatorHfeHadrons, processData, " Process for Data" , true );
268+ PROCESS_SWITCH (HfCorrelatorHfeHadrons, processData, " Process for Data" , false );
207269
208270 // ======= Process starts for McRec, Same event ============
209271
210272 void processMcRec (McTableCollision const & mcCollision,
211- aod::HfSelEl const & mcElectron,
273+ aod::HfCorrSelEl const & mcElectron,
212274 McTableTracks const & mcTracks)
213275 {
214276 fillCorrelation (mcCollision, mcElectron, mcTracks);
215277 }
216278
217279 PROCESS_SWITCH (HfCorrelatorHfeHadrons, processMcRec, " Process MC Reco mode" , false );
218280
281+ void processMcGen (McGenTableCollision const & mcCollision, aod::McParticles const & mcParticles, aod::HfMcGenSelEl const & electron)
282+ {
283+
284+ BinningTypeMcGen corrBinningMcGen{{zBins, multBinsMcGen}, true };
285+ int poolBin = corrBinningMcGen.getBin (std::make_tuple (mcCollision.posZ (), mcCollision.multMCFT0A ()));
286+
287+ double ptElectron = 0 ;
288+ double phiElectron = 0 ;
289+ double etaElectron = 0 ;
290+ for (const auto & electronMc : electron) {
291+ double ptHadron = 0 ;
292+ double phiHadron = 0 ;
293+ double etaHadron = 0 ;
294+ double deltaPhi = 0 ;
295+ double deltaEta = 0 ;
296+ ptElectron = electronMc.ptTrackMc ();
297+ phiElectron = electronMc.phiTrackMc ();
298+ etaElectron = electronMc.etaTrackMc ();
299+ for (const auto & particleMc : mcParticles) {
300+ if (particleMc.globalIndex () == electronMc.trackId ()) {
301+
302+ continue ;
303+ }
304+
305+ // Associated hadron Selection //////
306+ if (!particleMc.isPhysicalPrimary ()) {
307+ continue ;
308+ }
309+
310+ if (particleMc.eta () < etaTrackMin || particleMc.eta () > etaTrackMax) {
311+ continue ;
312+ }
313+ if (particleMc.pt () < ptTrackMin) {
314+ continue ;
315+ }
316+ ptHadron = particleMc.pt ();
317+ phiHadron = particleMc.phi ();
318+ etaHadron = particleMc.eta ();
319+ if (ptCondition && (ptElectron < ptHadron)) {
320+ return ; // Apply pT condition
321+ }
322+ deltaPhi = RecoDecay::constrainAngle (phiElectron - phiHadron, -o2::constants::math::PIHalf);
323+ deltaEta = etaElectron - etaHadron;
324+ bool isNonHfeCorr = false ;
325+ if (electronMc.isNonHfeMc ()) {
326+
327+ registry.fill (HIST (" hMCgenNonHfEHCorrel" ), ptElectron, ptHadron, deltaPhi, deltaEta);
328+ isNonHfeCorr = true ;
329+ } else {
330+
331+ registry.fill (HIST (" hMCgenInclusiveEHCorrl" ), ptElectron, ptHadron, deltaPhi, deltaEta);
332+ }
333+ entryElectronHadronPairmcGen (deltaPhi, deltaEta, ptElectron, ptHadron, poolBin, isNonHfeCorr);
334+ }
335+ }
336+ }
337+ PROCESS_SWITCH (HfCorrelatorHfeHadrons, processMcGen, " Process MC Gen mode" , true );
338+ // ====================== Implement Event mixing on Data ===============================
339+
219340 // ====================== Implement Event mixing on Data ===================================
220341
221- void processDataMixedEvent (TableCollisions const & collision, aod::HfSelEl const & electron, TableTracks const & tracks)
342+ void processDataMixedEvent (TableCollisions const & collision, aod::HfCorrSelEl const & electron, TableTracks const & tracks)
222343 {
223344 auto tracksTuple = std::make_tuple (electron, tracks);
224- Pair<TableCollisions, aod::HfSelEl , TableTracks, BinningType> pair{corrBinning, 5 , -1 , collision, tracksTuple, &cache};
345+ Pair<TableCollisions, aod::HfCorrSelEl , TableTracks, BinningType> pair{corrBinning, 5 , -1 , collision, tracksTuple, &cache};
225346
226347 // loop over the rows of the new table
227- for (auto & [c1, tracks1, c2, tracks2] : pair) {
348+ for (const auto & [c1, tracks1, c2, tracks2] : pair) {
228349
229350 fillMixCorrelation (c1, c2, tracks1, tracks2);
230351 }
@@ -233,20 +354,71 @@ struct HfCorrelatorHfeHadrons {
233354
234355 // ====================== Implement Event mixing on McRec ===================================
235356
236- void processMcRecMixedEvent (McTableCollisions const & mccollision, aod::HfSelEl const & electron, McTableTracks const & mcTracks)
357+ void processMcRecMixedEvent (McTableCollisions const & mccollision, aod::HfCorrSelEl const & electron, McTableTracks const & mcTracks)
237358 {
238359 auto tracksTuple = std::make_tuple (electron, mcTracks);
239- Pair<McTableCollisions, aod::HfSelEl , McTableTracks, BinningType> pairMcRec{corrBinning, 5 , -1 , mccollision, tracksTuple, &cache};
360+ Pair<McTableCollisions, aod::HfCorrSelEl , McTableTracks, BinningType> pairMcRec{corrBinning, 5 , -1 , mccollision, tracksTuple, &cache};
240361
241362 // loop over the rows of the new table
242- for (auto & [c1, tracks1, c2, tracks2] : pairMcRec) {
363+ for (const auto & [c1, tracks1, c2, tracks2] : pairMcRec) {
243364
244365 fillMixCorrelation (c1, c2, tracks1, tracks2);
245366 }
246367 }
247368 PROCESS_SWITCH (HfCorrelatorHfeHadrons, processMcRecMixedEvent, " Process Mixed Event MC Reco mode" , false );
248- };
369+ void processMcGenMixedEvent (McGenTableCollisions const & mcCollision, aod::HfMcGenSelEl const & electrons, aod::McParticles const & mcParticles)
370+ {
371+
372+ BinningTypeMcGen corrBinningMcGen{{zBins, multBinsMcGen}, true };
373+
374+ auto tracksTuple = std::make_tuple (electrons, mcParticles);
375+ Pair<McGenTableCollisions, aod::HfMcGenSelEl, aod::McParticles, BinningTypeMcGen> pairMcGen{corrBinningMcGen, 5 , -1 , mcCollision, tracksTuple, &cache};
249376
377+ // loop over the rows of the new table
378+ double ptElectronMix = -999 ;
379+ double phiElectronMix = -999 ;
380+ double etaElectronMix = -999 ;
381+ double deltaPhiMix = -999 ;
382+ double deltaEtaMix = -999 ;
383+ double ptHadronMix = -999 ;
384+ double etaHadronMix = -999 ;
385+ double phiHadronMix = -999 ;
386+ for (const auto & [c1, tracks1, c2, tracks2] : pairMcGen) {
387+ int poolBin = corrBinningMcGen.getBin (std::make_tuple (c1.posZ (), c1.multMCFT0A ()));
388+ for (const auto & [t1, t2] : combinations (CombinationsFullIndexPolicy (tracks1, tracks2))) {
389+ ptHadronMix = t2.pt ();
390+ ptElectronMix = t1.ptTrackMc ();
391+ phiElectronMix = t1.phiTrackMc ();
392+ phiHadronMix = t2.phi ();
393+ etaElectronMix = t1.etaTrackMc ();
394+ etaHadronMix = t2.eta ();
395+ if (t2.eta () < etaTrackMin || t2.eta () > etaTrackMax) {
396+ continue ;
397+ }
398+ if (t2.pt () < ptTrackMin) {
399+ continue ;
400+ }
401+ if (ptCondition && (ptElectronMix < ptHadronMix)) {
402+ continue ;
403+ }
404+
405+ deltaPhiMix = RecoDecay::constrainAngle (phiElectronMix - phiHadronMix, -o2::constants::math::PIHalf);
406+ deltaEtaMix = etaElectronMix - etaHadronMix;
407+ bool isNonHfeCorr = false ;
408+ if (t1.isNonHfeMc ()) {
409+ isNonHfeCorr = true ;
410+ registry.fill (HIST (" hMixEventMcGenNonHfEHCorrl" ), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix);
411+ } else {
412+
413+ registry.fill (HIST (" hMixEventMcGenInclusiveEHCorrl" ), ptElectronMix, ptHadronMix, deltaPhiMix, deltaEtaMix);
414+ }
415+
416+ entryElectronHadronPairmcGen (deltaPhiMix, deltaEtaMix, ptElectronMix, ptHadronMix, poolBin, isNonHfeCorr);
417+ }
418+ }
419+ }
420+ PROCESS_SWITCH (HfCorrelatorHfeHadrons, processMcGenMixedEvent, " Process Mixed Event MC Gen mode" , false );
421+ };
250422WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
251423{
252424 return WorkflowSpec{
0 commit comments