1313// Analysis task to produce smeared pt, eta, phi for electrons/muons in dilepton analysis
1414// Please write to: daiki.sekihata@cern.ch
1515
16+ #include < array>
1617#include < string>
1718#include < chrono>
1819
@@ -33,18 +34,24 @@ using namespace o2::framework;
3334using namespace o2 ::framework::expressions;
3435using namespace o2 ::aod;
3536
37+ namespace o2 ::aod::pwgem::dilepton::smearing
38+ {
39+ enum class EMAnaType : int {
40+ kEfficiency = 0 ,
41+ kCocktail = 1 ,
42+ };
43+ } // namespace o2::aod::pwgem::dilepton::smearing
44+
3645struct ApplySmearing {
37- enum class EMAnaType : int {
38- kEfficiency = 0 ,
39- kCocktail = 1 ,
40- };
4146
4247 Produces<aod::SmearedElectrons> smearedelectron;
4348 Produces<aod::SmearedMuons> smearedmuon;
4449
4550 Configurable<bool > fFromCcdb {" cfgFromCcdb" , false , " get resolution and efficiency histos from CCDB" };
4651 Configurable<std::string> fConfigCcdbUrl {" cfgCcdbUrl" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
4752 Configurable<int64_t > fTimestamp {" cfgCcdbTimestamp" , 10 , " valid timestamp of CCDB object" };
53+ Configurable<float > fCentralityForCocktail {" cfgCentralityForCocktail" , 5 , " average centrality for cocktail" };
54+ Configurable<int > cfgCentEstimator{" cfgCentEstimator" , 2 , " FT0M:0, FT0A:1, FT0C:2" };
4855
4956 struct : ConfigurableGroup {
5057 std::string prefix = " electron_filename_group" ;
@@ -62,6 +69,7 @@ struct ApplySmearing {
6269 Configurable<std::string> fConfigCcdbPathRes {" cfgCcdbPathRes" , " " , " path to the ccdb object for resolution" };
6370 Configurable<std::string> fConfigCcdbPathEff {" cfgCcdbPahtEff" , " " , " path to the ccdb object for efficiency" };
6471 Configurable<std::string> fConfigCcdbPathDCA {" cfgCcdbPahtDCA" , " " , " path to the ccdb object for dca" };
72+ Configurable<float > fConfigMinPt {" cfgMinPt" , -1 , " if ptgen is smaller than this threshold, this value is used as input for ptgen." };
6573 } electron_filenames;
6674
6775 struct : ConfigurableGroup {
@@ -80,6 +88,7 @@ struct ApplySmearing {
8088 Configurable<std::string> fConfigCcdbPathRes {" cfgCcdbPathRes" , " " , " path to the ccdb object for resolution" };
8189 Configurable<std::string> fConfigCcdbPathEff {" cfgCcdbPahtEff" , " " , " path to the ccdb object for efficiency" };
8290 Configurable<std::string> fConfigCcdbPathDCA {" cfgCcdbPahtDCA" , " " , " path to the ccdb object for dca" };
91+ Configurable<float > fConfigMinPt {" cfgMinPt" , -1 , " if ptgen is smaller than this threshold, this value is used as input for ptgen." };
8392 } sa_muon_filenames;
8493
8594 struct : ConfigurableGroup {
@@ -98,6 +107,7 @@ struct ApplySmearing {
98107 Configurable<std::string> fConfigCcdbPathRes {" cfgCcdbPathRes" , " " , " path to the ccdb object for resolution" };
99108 Configurable<std::string> fConfigCcdbPathEff {" cfgCcdbPahtEff" , " " , " path to the ccdb object for efficiency" };
100109 Configurable<std::string> fConfigCcdbPathDCA {" cfgCcdbPahtDCA" , " " , " path to the ccdb object for dca" };
110+ Configurable<float > fConfigMinPt {" cfgMinPt" , -1 , " if ptgen is smaller than this threshold, this value is used as input for ptgen." };
101111 } gl_muon_filenames;
102112
103113 MomentumSmearer smearer_Electron;
@@ -118,6 +128,7 @@ struct ApplySmearing {
118128 smearer_Electron.setEffHistName (TString (electron_filenames.fConfigEffHistName ));
119129 smearer_Electron.setDCAFileName (TString (electron_filenames.fConfigDCAFileName ));
120130 smearer_Electron.setDCAHistName (TString (electron_filenames.fConfigDCAHistName ));
131+ smearer_Electron.setMinPt (electron_filenames.fConfigMinPt );
121132
122133 smearer_StandaloneMuon.setNDSmearing (sa_muon_filenames.fConfigNDSmearing .value );
123134 smearer_StandaloneMuon.setResFileName (TString (sa_muon_filenames.fConfigResFileName ));
@@ -130,6 +141,7 @@ struct ApplySmearing {
130141 smearer_StandaloneMuon.setEffHistName (TString (sa_muon_filenames.fConfigEffHistName ));
131142 smearer_StandaloneMuon.setDCAFileName (TString (sa_muon_filenames.fConfigDCAFileName ));
132143 smearer_StandaloneMuon.setDCAHistName (TString (sa_muon_filenames.fConfigDCAHistName ));
144+ smearer_StandaloneMuon.setMinPt (sa_muon_filenames.fConfigMinPt );
133145
134146 smearer_GlobalMuon.setNDSmearing (gl_muon_filenames.fConfigNDSmearing .value );
135147 smearer_GlobalMuon.setResFileName (TString (gl_muon_filenames.fConfigResFileName ));
@@ -142,6 +154,7 @@ struct ApplySmearing {
142154 smearer_GlobalMuon.setEffHistName (TString (gl_muon_filenames.fConfigEffHistName ));
143155 smearer_GlobalMuon.setDCAFileName (TString (gl_muon_filenames.fConfigDCAFileName ));
144156 smearer_GlobalMuon.setDCAHistName (TString (gl_muon_filenames.fConfigDCAHistName ));
157+ smearer_GlobalMuon.setMinPt (gl_muon_filenames.fConfigMinPt );
145158
146159 if (fFromCcdb ) {
147160 ccdb->setURL (fConfigCcdbUrl );
@@ -172,8 +185,10 @@ struct ApplySmearing {
172185 smearer_GlobalMuon.init ();
173186 }
174187
175- template <EMAnaType type, typename TTracksMC, typename TCollisions, typename TMCCollisions>
176- void applySmearing (TTracksMC const & tracksMC, TCollisions const &, TMCCollisions const &)
188+ PresliceUnsorted<aod::EMMCEventLabels> recColperMcCollision = aod::emmceventlabel::emmceventId;
189+
190+ template <o2::aod::pwgem::dilepton::smearing::EMAnaType type, typename TTracksMC, typename TCollisions, typename TMCCollisions>
191+ void applySmearing (TTracksMC const & tracksMC, TCollisions const & collisions, TMCCollisions const &)
177192 {
178193 for (auto & mctrack : tracksMC) {
179194 float ptgen = mctrack.pt ();
@@ -182,11 +197,30 @@ struct ApplySmearing {
182197 float efficiency = 1 .;
183198 float dca = 0 .;
184199
185- float centrality = 105 .f ;
186- if constexpr (type == EMAnaType::kEfficiency ) {
187- centrality = 0 ; // to be implemented later.
200+ float ptsmeared = 0 , etasmeared = 0 , phismeared = 0 ;
201+ float centrality = -1 .f ;
202+ if constexpr (type == o2::aod::pwgem::dilepton::smearing::EMAnaType::kEfficiency ) {
203+ auto mccollision = mctrack.template emmcevent_as <TMCCollisions>();
204+ auto rec_colls_per_mccoll = collisions.sliceBy (recColperMcCollision, mccollision.globalIndex ());
205+ uint32_t maxNumContrib = 0 ;
206+ int rec_col_globalIndex = -999 ;
207+ for (auto & rec_col : rec_colls_per_mccoll) {
208+ if (rec_col.numContrib () > maxNumContrib) {
209+ rec_col_globalIndex = rec_col.globalIndex ();
210+ maxNumContrib = rec_col.numContrib (); // assign mc collision to collision where the number of contibutor is lager. LF/MM recommendation
211+ }
212+ }
213+
214+ if (rec_colls_per_mccoll.size () > 0 ) { // if mc collisions are not reconstructed, such mc collisions should not enter efficiency calculation.
215+ auto collision = collisions.rawIteratorAt (rec_col_globalIndex);
216+ centrality = std::array{collision.centFT0M (), collision.centFT0A (), collision.centFT0C ()}[cfgCentEstimator];
217+ } else {
218+ ptsmeared = ptgen;
219+ etasmeared = etagen;
220+ phismeared = phigen;
221+ }
188222 } else {
189- centrality = 0 ;
223+ centrality = fCentralityForCocktail ;
190224 }
191225
192226 int pdgCode = mctrack.pdgCode ();
@@ -196,7 +230,6 @@ struct ApplySmearing {
196230 ch = 1 ;
197231 }
198232 // apply smearing for electrons or muons.
199- float ptsmeared, etasmeared, phismeared;
200233 smearer_Electron.applySmearing (centrality, ch, ptgen, etagen, phigen, ptsmeared, etasmeared, phismeared);
201234 // get the efficiency
202235 efficiency = smearer_Electron.getEfficiency (ptgen, etagen, phigen);
@@ -229,12 +262,12 @@ struct ApplySmearing {
229262 smearedelectron (ptgen, etagen, phigen, efficiency, dca);
230263 smearedmuon (ptgen, etagen, phigen, efficiency, dca, ptgen, etagen, phigen, efficiency, dca);
231264 }
232- }
265+ } // end of mc track loop
233266 }
234267
235- void processMCanalysisEM (aod::EMMCParticles const & tracksMC, aod::EMEvents const & collisions, aod::EMMCEvents const & mccollisions)
268+ void processMCanalysisEM (aod::EMMCParticles const & tracksMC, soa::Join< aod::EMEvents, aod::EMEventsCent, aod::EMMCEventLabels> const & collisions, aod::EMMCEvents const & mccollisions)
236269 {
237- applySmearing<EMAnaType::kEfficiency >(tracksMC, collisions, mccollisions);
270+ applySmearing<o2::aod::pwgem::dilepton::smearing:: EMAnaType::kEfficiency >(tracksMC, collisions, mccollisions);
238271 }
239272
240273 // void processMCanalysisDQ(ReducedMCTracks const& tracksMC)
@@ -244,7 +277,7 @@ struct ApplySmearing {
244277
245278 void processCocktail (aod::McParticles const & tracksMC)
246279 {
247- applySmearing<EMAnaType::kCocktail >(tracksMC, nullptr , nullptr );
280+ applySmearing<o2::aod::pwgem::dilepton::smearing:: EMAnaType::kCocktail >(tracksMC, nullptr , nullptr );
248281 }
249282
250283 void processDummyCocktail (aod::McParticles const & tracksMC)
@@ -317,14 +350,24 @@ struct CheckSmearing {
317350 }
318351 }
319352
320- template <typename TTracksMC>
321- void Check (TTracksMC const & tracksMC)
353+ PresliceUnsorted<aod::EMMCEventLabels> recColperMcCollision = aod::emmceventlabel::emmceventId;
354+
355+ template <o2::aod::pwgem::dilepton::smearing::EMAnaType type, typename TTracksMC, typename TCollisions, typename TMCCollisions>
356+ void Check (TTracksMC const & tracksMC, TCollisions const & collisions, TMCCollisions const &)
322357 {
323358 for (auto & mctrack : tracksMC) {
324359 if (abs (mctrack.pdgCode ()) != fPdgCode ) {
325360 continue ;
326361 }
327362
363+ if constexpr (type == o2::aod::pwgem::dilepton::smearing::EMAnaType::kEfficiency ) {
364+ auto mccollision = mctrack.template emmcevent_as <TMCCollisions>();
365+ auto rec_colls_per_mccoll = collisions.sliceBy (recColperMcCollision, mccollision.globalIndex ());
366+ if (rec_colls_per_mccoll.size () < 1 ) { // if mc collisions are not reconstructed, such mc collisions should not enter efficiency calculation.
367+ continue ;
368+ }
369+ }
370+
328371 float deltaptoverpt = -1000 .;
329372 if (mctrack.pt () > 0 .)
330373 deltaptoverpt = (mctrack.pt () - mctrack.ptSmeared ()) / mctrack.pt ();
@@ -343,9 +386,9 @@ struct CheckSmearing {
343386 } // end of mctrack loop
344387 }
345388
346- void processCheckMCanalysisEM (EMMCParticlesWithSmearing const & tracksMC)
389+ void processCheckMCanalysisEM (EMMCParticlesWithSmearing const & tracksMC, soa::Join<aod::EMEvents, aod::EMEventsCent, aod::EMMCEventLabels> const & collisions, aod::EMMCEvents const & mccollisions )
347390 {
348- Check (tracksMC);
391+ Check<o2::aod::pwgem::dilepton::smearing::EMAnaType:: kEfficiency > (tracksMC, collisions, mccollisions );
349392 }
350393
351394 // void processCheckMCanalysisDQ(MyReducedTracks const& tracksMC)
@@ -355,7 +398,7 @@ struct CheckSmearing {
355398
356399 void processCheckCocktail (MyCocktailTracks const & tracksMC)
357400 {
358- Check (tracksMC);
401+ Check<o2::aod::pwgem::dilepton::smearing::EMAnaType:: kCocktail > (tracksMC, nullptr , nullptr );
359402 }
360403
361404 void processDummyMCanalysisEM (aod::EMMCParticles const &) {}
0 commit comments