3232#include " Framework/AnalysisDataModel.h"
3333#include " Framework/AnalysisTask.h"
3434#include " Framework/HistogramRegistry.h"
35+ #include " Framework/O2DatabasePDGPlugin.h"
3536#include " Framework/StepTHn.h"
3637#include " Framework/runDataProcessing.h"
3738#include " ReconstructionDataFormats/Track.h"
@@ -153,6 +154,11 @@ struct Kstar892LightIon {
153154
154155 // Fixed variables
155156 float lowPtCutPID = 0.5 ;
157+
158+ Configurable<bool > selHasFT0{" selHasFT0" , true , " Has FT0?" };
159+ Configurable<bool > isZvtxPosSelMC{" isZvtxPosSelMC" , true , " Zvtx position selection for MC events?" };
160+ Configurable<bool > selTVXMC{" selTVXMC" , true , " apply TVX selection in MC?" };
161+ Configurable<bool > selINELgt0{" selINELgt0" , true , " Select INEL > 0?" };
156162 } selectionConfig;
157163
158164 Configurable<bool > calcLikeSign{" calcLikeSign" , true , " Calculate Like Sign" };
@@ -168,6 +174,12 @@ struct Kstar892LightIon {
168174
169175 Configurable<int > reflectionType{" reflectionType" , 0 , " Reflection: 0=Rho, 1=Omega, 2=Phi, 3=Kstar (for processRecReflection)" };
170176
177+ Configurable<float > nchAcceptance{" nchAcceptance" , 0.5 , " Eta window to measure Nch MC for Nch vs Cent distribution" };
178+
179+ Configurable<int > nBinsNch{" nBinsNch" , 400 , " N bins Nch (|eta|<0.8)" };
180+ Configurable<float > minNch{" minNch" , 0 , " Min Nch (|eta|<0.8)" };
181+ Configurable<float > maxNch{" maxNch" , 400 , " Max Nch (|eta|<0.8)" };
182+
171183 // Configurable for histograms
172184 ConfigurableAxis binsCentPlot{" binsCentPlot" , {110 , 0.0 , 110 }, " Centrality axis" };
173185 ConfigurableAxis axisdEdx{" axisdEdx" , {1 , 0 .0f , 200 .0f }, " dE/dx (a.u.)" };
@@ -369,6 +381,39 @@ struct Kstar892LightIon {
369381 if (doprocessRecReflection) {
370382 hMC.add (" Reflections/hReflection" , " Refelction template of Rho" , kTH3F , {ptAxis, centralityAxis, invmassAxis});
371383 }
384+
385+ if (doprocessMCCheck) {
386+ hMC.add (" MCCheck/CentVsFoundFT0" , " Found(=1.5) NOT Found(=0.5);;Status;" , kTH2F , {{{centralityAxis}, {2 , 0 , 2 }}});
387+ hMC.add (" MCCheck/zPosMC" , " Generated Events With at least One Rec. Collision + Sel. criteria;;Entries;" , kTH1F , {vertexZAxis});
388+ hMC.add (" MCCheck/zPos" , " With Event Selection;;Entries;" , kTH1F , {vertexZAxis});
389+ hMC.add (" MCCheck/Cent" , " ;;Entries" , kTH1F , {centralityAxis});
390+ hMC.add (" MCCheck/NchVsCent" , " Measured Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Nch" , kTH2F , {{centralityAxis, {nBinsNch, minNch, maxNch}}});
391+
392+ // MC events passing the TVX requirement
393+ hMC.add (" MCCheck/NchMCcentVsTVX" , " ;Passed(=1.5) NOT Passed(=0.5);" , kTH2F , {{{nBinsNch, minNch, maxNch}, {2 , 0 , 2 }}});
394+
395+ hMC.add (" MCCheck/NumberOfRecoCollisions" , " Number of times Gen. Coll.are reconstructed;N;Entries" , kTH1F , {{10 , -0.5 , 9.5 }});
396+
397+ // Needed for the Gen. Nch to Centrality conversion
398+ hMC.add (" MCCheck/NchMCVsCent" , " Generated Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Gen. Nch MC (|#eta|<0.8)" , kTH2F , {{centralityAxis, {nBinsNch, minNch, maxNch}}});
399+
400+ // Needed to measure Event Loss
401+ hMC.add (" MCCheck/NchMC_WithRecoEvt" , " Generated Nch of Evts With at least one Rec. Coll. + Sel. criteria;Gen. Nch MC (|#eta|<0.8);Entries" , kTH1F , {{nBinsNch, minNch, maxNch}});
402+ hMC.add (" MCCheck/NchMC_AllGen" , " Generated Nch of All Gen. Evts.;Gen. Nch;Entries" , kTH1F , {{nBinsNch, minNch, maxNch}});
403+
404+ // Needed to measure Event Splitting
405+ hMC.add (" MCCheck/Centrality_WRecoEvt" , " Generated Events With at least One Rec. Collision And NO Sel. criteria;;Entries" , kTH1F , {centralityAxis});
406+ hMC.add (" MCCheck/Centrality_WRecoEvtWSelCri" , " Generated Events With at least One Rec. Collision + Sel. criteria;;Entries" , kTH1F , {centralityAxis});
407+ hMC.add (" MCCheck/Centrality_AllRecoEvt" , " Generated Events Irrespective of the number of times it was reconstructed + Evt. Selections;;Entries" , kTH1F , {centralityAxis});
408+
409+ hMC.add (" MCCheck/PtKstarVsCentMC_WithRecoEvt" , " Generated Events With at least One Rec. Collision;;;" , kTH2F , {ptAxis, centralityAxis});
410+
411+ // Needed to calculate the numerator of the Signal Loss correction
412+ hMC.add (" MCCheck/PtKstarVsNchMC_WithRecoEvt" , " Generated Events With at least One Rec. Collision;;Gen. Nch (|#eta|<0.8);" , kTH2F , {{ptAxis, {nBinsNch, minNch, maxNch}}});
413+
414+ // Needed to calculate the denominator of the Signal Loss correction
415+ hMC.add (" MCCheck/PtKstarVsNchMC_AllGen" , " All Generated Events;;Gen. Nch (|#eta|<0.8);" , kTH2F , {{ptAxis, {nBinsNch, minNch, maxNch}}});
416+ }
372417 }
373418
374419 double massPi = o2::constants::physics::MassPiPlus;
@@ -1551,7 +1596,8 @@ struct Kstar892LightIon {
15511596 hMC.fill (HIST (" ImpactCorr/hImpactParameterGen" ), impactPar);
15521597
15531598 bool isSelectedEvent = false ;
1554- auto centrality = -999 .;
1599+ centrality = -1 .f ;
1600+
15551601 for (const auto & RecCollision : recCollisions) {
15561602 if (!RecCollision.has_mcCollision ())
15571603 continue ;
@@ -1602,7 +1648,7 @@ struct Kstar892LightIon {
16021648 hMC.fill (HIST (" LossMult/hMultMC" ), multMC);
16031649
16041650 bool isSelectedEvent = false ;
1605- float centrality = -1 .f ;
1651+ centrality = -1 .f ;
16061652
16071653 for (auto const & collision : recCollisions) {
16081654
@@ -1949,6 +1995,230 @@ struct Kstar892LightIon {
19491995 }
19501996 }
19511997 PROCESS_SWITCH (Kstar892LightIon, processRecReflection, " Process particle reflection" , false );
1998+
1999+ Service<o2::framework::O2DatabasePDG> pdg;
2000+
2001+ void processMCCheck (aod::McCollisions::iterator const & mccollision, soa::SmallGroups<EventCandidatesMC> const & collisions, aod::McParticles const & mcParticles, TrackCandidatesMC const &)
2002+ {
2003+
2004+ // ---------------------------
2005+ // Only INEL > 0 generated collisions
2006+ // By counting number of primary charged particles in |eta| < 1
2007+ // ---------------------------
2008+ int nChMC{0 };
2009+ int nChMCEta08{0 };
2010+ int nChFT0A{0 };
2011+ int nChFT0C{0 };
2012+ static constexpr float MinCharge{3 .f };
2013+ static constexpr float MinFT0A{3 .5f };
2014+ static constexpr float MaxFT0A{4 .9f };
2015+ static constexpr float MinFT0C{-3 .3f };
2016+ static constexpr float MaxFT0C{-2 .1f };
2017+ static constexpr float One{1 .0f };
2018+ static constexpr int ZeroInt{0 };
2019+
2020+ for (const auto & particle : mcParticles) {
2021+
2022+ auto charge{0 .};
2023+ // Get the MC particle
2024+ const auto * pdgParticle = pdg->GetParticle (particle.pdgCode ());
2025+ if (pdgParticle != nullptr ) {
2026+ charge = pdgParticle->Charge ();
2027+ } else {
2028+ continue ;
2029+ }
2030+
2031+ // Is it a charged particle?
2032+ if (std::abs (charge) < MinCharge)
2033+ continue ;
2034+
2035+ // Is it a primary particle?
2036+ if (!particle.isPhysicalPrimary ())
2037+ continue ;
2038+
2039+ const float eta{particle.eta ()};
2040+
2041+ // TVX requirement
2042+ if (eta > MinFT0A && eta < MaxFT0A) {
2043+ nChFT0A++;
2044+ }
2045+
2046+ if (eta > MinFT0C && eta < MaxFT0C) {
2047+ nChFT0C++;
2048+ }
2049+
2050+ if (std::abs (eta) < nchAcceptance) {
2051+ nChMCEta08++;
2052+ }
2053+
2054+ // INEL > 0
2055+ if (std::abs (eta) > One)
2056+ continue ;
2057+
2058+ nChMC++;
2059+ }
2060+
2061+ // ---------------------------
2062+ // Only events with at least one charged particle in the FT0A and FT0C acceptances
2063+ // ---------------------------
2064+ if (selectionConfig.selTVXMC ) {
2065+ if (!(nChFT0A > ZeroInt && nChFT0C > ZeroInt)) {
2066+ hMC.fill (HIST (" MCCheck/NchMCcentVsTVX" ), nChMC, 0.5 );
2067+ return ;
2068+ }
2069+ hMC.fill (HIST (" MCCheck/NchMCcentVsTVX" ), nChMC, 1.5 );
2070+ }
2071+
2072+ // ---------------------------
2073+ // Only MC events with |Vtx Z| < 10 cm
2074+ // ---------------------------
2075+ if (selectionConfig.isZvtxPosSelMC && (std::fabs (mccollision.posZ ()) > selectionConfig.cfgVrtxZCut )) {
2076+ return ;
2077+ }
2078+
2079+ // ---------------------------
2080+ // Only INEL > 0 generated events
2081+ // ---------------------------
2082+ if (selectionConfig.selINELgt0 ) {
2083+ if (!(nChMC > ZeroInt)) {
2084+ return ;
2085+ }
2086+ }
2087+
2088+ const auto & nRecColls{collisions.size ()};
2089+ hMC.fill (HIST (" MCCheck/NumberOfRecoCollisions" ), nRecColls);
2090+
2091+ // ---------------------------
2092+ // Only Generated evets with at least one reconstrued collision
2093+ // ---------------------------
2094+ if (nRecColls > ZeroInt) {
2095+
2096+ // Finds the collisions with the largest number of contributors
2097+ // in case nRecColls is larger than One
2098+ int biggestNContribs{-1 };
2099+ int bestCollisionIndex{-1 };
2100+ centrality = -1 .f ;
2101+ for (const auto & collision : collisions) {
2102+
2103+ if (selectCentEstimator == kFT0M ) {
2104+ centrality = collision.centFT0M ();
2105+ } else if (selectCentEstimator == kFT0A ) {
2106+ centrality = collision.centFT0A ();
2107+ } else if (selectCentEstimator == kFT0C ) {
2108+ centrality = collision.centFT0C ();
2109+ } else if (selectCentEstimator == kFV0A ) {
2110+ centrality = collision.centFV0A ();
2111+ } else {
2112+ centrality = collision.centFT0M (); // default
2113+ }
2114+
2115+ if (selectionConfig.selHasFT0 && !collision.has_foundFT0 ()) {
2116+ continue ;
2117+ }
2118+
2119+ if (biggestNContribs < collision.numContrib ()) {
2120+ biggestNContribs = collision.numContrib ();
2121+ bestCollisionIndex = collision.globalIndex ();
2122+ }
2123+
2124+ // Needed to calculate denominator of the Event Splitting correction
2125+ if (selectionEvent (collision, false )) {
2126+ hMC.fill (HIST (" MCCheck/Centrality_AllRecoEvt" ), centrality);
2127+ }
2128+ }
2129+
2130+ // ---------------------------
2131+ // Loop over the reconstructed collisions
2132+ // Only that one with the largest number of contributors is considered
2133+ // ---------------------------
2134+ centrality = -1 .f ;
2135+ for (const auto & collision : collisions) {
2136+
2137+ if (selectCentEstimator == kFT0M ) {
2138+ centrality = collision.centFT0M ();
2139+ } else if (selectCentEstimator == kFT0A ) {
2140+ centrality = collision.centFT0A ();
2141+ } else if (selectCentEstimator == kFT0C ) {
2142+ centrality = collision.centFT0C ();
2143+ } else if (selectCentEstimator == kFV0A ) {
2144+ centrality = collision.centFV0A ();
2145+ } else {
2146+ centrality = collision.centFT0M (); // default
2147+ }
2148+
2149+ // ---------------------------
2150+ // Reject collisions if has_foundFT0() returns false
2151+ // ---------------------------
2152+ if (selectionConfig.selHasFT0 && !collision.has_foundFT0 ()) {
2153+ hMC.fill (HIST (" MCCheck/CentVsFoundFT0" ), centrality, 0.5 );
2154+ continue ;
2155+ }
2156+ hMC.fill (HIST (" MCCheck/CentVsFoundFT0" ), centrality, 1.5 );
2157+
2158+ // ---------------------------
2159+ // Pick the collisions with the largest number of contributors
2160+ // ---------------------------
2161+ if (bestCollisionIndex != collision.globalIndex ()) {
2162+ continue ;
2163+ }
2164+
2165+ // ---------------------------
2166+ // Needed to construct the correlation between MC Nch v.s. centrality
2167+ // ---------------------------
2168+
2169+ hMC.fill (HIST (" MCCheck/Centrality_WRecoEvt" ), centrality);
2170+ hMC.fill (HIST (" MCCheck/zPosMC" ), mccollision.posZ ());
2171+
2172+ // ---------------------------
2173+ // Event selection
2174+ // for reconstructed collisions
2175+ // ---------------------------
2176+ if (!selectionEvent (collision, false )) {
2177+ continue ;
2178+ }
2179+
2180+ hMC.fill (HIST (" MCCheck/Centrality_WRecoEvtWSelCri" ), centrality);
2181+ hMC.fill (HIST (" MCCheck/NchMCVsCent" ), centrality, nChMCEta08);
2182+ hMC.fill (HIST (" MCCheck/NchMC_WithRecoEvt" ), nChMCEta08); // Numerator of event loss correction
2183+ hMC.fill (HIST (" MCCheck/zPos" ), collision.posZ ());
2184+ hMC.fill (HIST (" MCCheck/Cent" ), centrality);
2185+
2186+ // ---------------------------
2187+ // All Generated events with at least one associated reconstructed collision
2188+ // The Generated events are not subjected to any selection criteria
2189+ // However, the associated reconstructed collisions pass the selection criteria
2190+ // This histograms are used for the denominator of the tracking efficiency
2191+ // ---------------------------
2192+ for (const auto & mcPart : mcParticles) {
2193+ if ((mcPart.y () < selectionConfig.motherRapidityMin || mcPart.y () > selectionConfig.motherRapidityMax ) || std::abs (mcPart.pdgCode ()) != o2::constants::physics::kK0Star892 )
2194+ continue ;
2195+
2196+ hMC.fill (HIST (" MCCheck/PtKstarVsCentMC_WithRecoEvt" ), mcPart.pt (), centrality);
2197+ hMC.fill (HIST (" MCCheck/PtKstarVsNchMC_WithRecoEvt" ), mcPart.pt (), nChMCEta08); // Numerator of signal loss
2198+ } // Loop over generated particles per generated collision
2199+ // hMC.fill(HIST("MCCheck/NchVsCent"), centrality, nCh);
2200+ } // Loop over Reco. Collisions: Only the collisions with the largest number of contributors
2201+ } // If condition: Only simulated evets with at least one reconstrued collision
2202+
2203+ // ---------------------------
2204+ // All Generated events irrespective of whether there is an associated reconstructed collision
2205+ // Consequently, the centrality being a reconstructed quantity, might not always be available
2206+ // Therefore it is expressed as a function of the generated pT and the generated Nch in ∣eta∣ < 0.8
2207+ // This is used for the denominator of the signal loss correction
2208+ // ---------------------------
2209+ for (const auto & mcPart : mcParticles) {
2210+ if ((mcPart.y () < selectionConfig.motherRapidityMin || mcPart.y () > selectionConfig.motherRapidityMax ) || std::abs (mcPart.pdgCode ()) != o2::constants::physics::kK0Star892 )
2211+ continue ;
2212+
2213+ hMC.fill (HIST (" MCCheck/PtKstarVsNchMC_AllGen" ), mcPart.pt (), nChMCEta08);
2214+ } // Loop over Generated Particles
2215+
2216+ // ---------------------------
2217+ // This is used for the denominator of the event loss correction
2218+ // ---------------------------
2219+ hMC.fill (HIST (" MCCheck/NchMC_AllGen" ), nChMCEta08);
2220+ }
2221+ PROCESS_SWITCH (Kstar892LightIon, processMCCheck, " Cross-check MC analysis" , false );
19522222};
19532223
19542224WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments