diff --git a/PWGLF/DataModel/LFSigmaTables.h b/PWGLF/DataModel/LFSigmaTables.h index bd808cef106..fdeab068f44 100644 --- a/PWGLF/DataModel/LFSigmaTables.h +++ b/PWGLF/DataModel/LFSigmaTables.h @@ -9,19 +9,28 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Qvectors.h" + #include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" + +#include "Math/Vector3D.h" +#include "TVector3.h" + +#include +#include #ifndef PWGLF_DATAMODEL_LFSIGMATABLES_H_ #define PWGLF_DATAMODEL_LFSIGMATABLES_H_ +using std::array; + // Creating output TTree for sigma analysis namespace o2::aod { @@ -29,53 +38,173 @@ namespace o2::aod // for real data namespace sigma0Core { -DECLARE_SOA_COLUMN(SigmapT, sigmapT, float); -DECLARE_SOA_COLUMN(SigmaMass, sigmaMass, float); -DECLARE_SOA_COLUMN(SigmaRapidity, sigmaRapidity, float); -DECLARE_SOA_COLUMN(SigmaOPAngle, sigmaOPAngle, float); -DECLARE_SOA_COLUMN(SigmaCentrality, sigmaCentrality, float); -DECLARE_SOA_COLUMN(SigmaRunNumber, sigmaRunNumber, int); -DECLARE_SOA_COLUMN(SigmaTimestamp, sigmaTimestamp, uint64_t); +DECLARE_SOA_COLUMN(X, x, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(Z, z, float); +DECLARE_SOA_COLUMN(DCADaughters, dcadaughters, float); + +DECLARE_SOA_COLUMN(PhotonPx, photonPx, float); +DECLARE_SOA_COLUMN(PhotonPy, photonPy, float); +DECLARE_SOA_COLUMN(PhotonPz, photonPz, float); +DECLARE_SOA_COLUMN(PhotonMass, photonMass, float); + +DECLARE_SOA_COLUMN(LambdaPx, lambdaPx, float); +DECLARE_SOA_COLUMN(LambdaPy, lambdaPy, float); +DECLARE_SOA_COLUMN(LambdaPz, lambdaPz, float); +DECLARE_SOA_COLUMN(LambdaMass, lambdaMass, float); +DECLARE_SOA_COLUMN(AntiLambdaMass, antilambdaMass, float); + +//______________________________________________________ +// DYNAMIC COLUMNS +// Sigma0 +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Sigma0 px + [](float photonPx, float lambdaPx) -> float { return photonPx + lambdaPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Sigma0 py + [](float photonPy, float lambdaPy) -> float { return photonPy + lambdaPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Sigma0 pz + [](float photonPz, float lambdaPz) -> float { return photonPz + lambdaPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, + [](float photonPx, float photonPy, float lambdaPx, float lambdaPy) -> float { + return RecoDecay::pt(array{photonPx + lambdaPx, photonPy + lambdaPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Total momentum in GeV/c + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0Mass, sigma0Mass, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + std::array pVecPhotons{photonPx, photonPy, photonPz}; + std::array pVecLambda{lambdaPx, lambdaPy, lambdaPz}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0Y, sigma0Y, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::y(std::array{photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz}, o2::constants::physics::MassSigma0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Phi in the range [0, 2pi) + [](float photonPx, float photonPy, float lambdaPx, float lambdaPy) -> float { return RecoDecay::phi(photonPx + lambdaPx, photonPy + lambdaPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Pseudorapidity + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::eta(std::array{photonPx + lambdaPx, photonPy + lambdaPy, photonPz + lambdaPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Radius, radius, //! Sigma0 decay radius (2D, centered at zero) + [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); + +DECLARE_SOA_DYNAMIC_COLUMN(OPAngle, opAngle, + [](float photonPx, float photonPy, float photonPz, float lambdaPx, float lambdaPy, float lambdaPz) { + TVector3 v1(photonPx, photonPy, photonPz); + TVector3 v2(lambdaPx, lambdaPy, lambdaPz); + return v1.Angle(v2); + }); + +// Photon +DECLARE_SOA_DYNAMIC_COLUMN(PhotonPt, photonPt, //! Transverse momentum in GeV/c + [](float photonPx, float photonPy) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx, photonPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonP, photonp, //! Total momentum in GeV/c + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonPx, photonPy, photonPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonEta, photonEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::eta(std::array{photonPx, photonPy, photonPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonY, photonY, //! Rapidity + [](float photonPx, float photonPy, float photonPz) -> float { + return RecoDecay::y(std::array{photonPx, photonPy, photonPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonPhi, photonPhi, //! Phi in the range [0, 2pi) + [](float photonPx, float photonPy) -> float { return RecoDecay::phi(photonPx, photonPy); }); + +// Lambda/ALambda +DECLARE_SOA_DYNAMIC_COLUMN(LambdaPt, lambdaPt, //! Transverse momentum in GeV/c + [](float lambdaPx, float lambdaPy) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaPx, lambdaPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaP, lambdap, //! Total momentum in GeV/c + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaPx, lambdaPy, lambdaPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaEta, lambdaEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::eta(std::array{lambdaPx, lambdaPy, lambdaPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaY, lambdaY, //! Rapidity + [](float lambdaPx, float lambdaPy, float lambdaPz) -> float { + return RecoDecay::y(std::array{lambdaPx, lambdaPy, lambdaPz}, o2::constants::physics::MassLambda); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaPhi, lambdaPhi, //! Phi in the range [0, 2pi) + [](float lambdaPx, float lambdaPy) -> float { return RecoDecay::phi(lambdaPx, lambdaPy); }); } // namespace sigma0Core DECLARE_SOA_TABLE(Sigma0Cores, "AOD", "SIGMA0CORES", - sigma0Core::SigmapT, - sigma0Core::SigmaMass, - sigma0Core::SigmaRapidity, - sigma0Core::SigmaOPAngle, - sigma0Core::SigmaCentrality, - sigma0Core::SigmaRunNumber, - sigma0Core::SigmaTimestamp); + // Basic properties + sigma0Core::X, sigma0Core::Y, sigma0Core::Z, sigma0Core::DCADaughters, + sigma0Core::PhotonPx, sigma0Core::PhotonPy, sigma0Core::PhotonPz, sigma0Core::PhotonMass, + sigma0Core::LambdaPx, sigma0Core::LambdaPy, sigma0Core::LambdaPz, sigma0Core::LambdaMass, sigma0Core::AntiLambdaMass, + + // Dynamic columns + sigma0Core::Px, + sigma0Core::Py, + sigma0Core::Pz, + sigma0Core::Pt, + sigma0Core::P, + sigma0Core::Sigma0Mass, + sigma0Core::Sigma0Y, + sigma0Core::Phi, + sigma0Core::Eta, + sigma0Core::Radius, + sigma0Core::OPAngle, + + sigma0Core::PhotonPt, + sigma0Core::PhotonP, + sigma0Core::PhotonEta, + sigma0Core::PhotonY, + sigma0Core::PhotonPhi, + + sigma0Core::LambdaPt, + sigma0Core::LambdaP, + sigma0Core::LambdaEta, + sigma0Core::LambdaY, + sigma0Core::LambdaPhi); // For Photon extra info -namespace sigmaPhotonExtra +namespace sigma0PhotonExtra { -DECLARE_SOA_COLUMN(PhotonPt, photonPt, float); -DECLARE_SOA_COLUMN(PhotonMass, photonMass, float); +//______________________________________________________ +// REGULAR COLUMNS FOR SIGMA0PHOTON DECLARE_SOA_COLUMN(PhotonQt, photonQt, float); DECLARE_SOA_COLUMN(PhotonAlpha, photonAlpha, float); -DECLARE_SOA_COLUMN(PhotonRadius, photonRadius, float); DECLARE_SOA_COLUMN(PhotonCosPA, photonCosPA, float); DECLARE_SOA_COLUMN(PhotonDCADau, photonDCADau, float); DECLARE_SOA_COLUMN(PhotonDCANegPV, photonDCANegPV, float); DECLARE_SOA_COLUMN(PhotonDCAPosPV, photonDCAPosPV, float); +DECLARE_SOA_COLUMN(PhotonRadius, photonRadius, float); DECLARE_SOA_COLUMN(PhotonZconv, photonZconv, float); -DECLARE_SOA_COLUMN(PhotonEta, photonEta, float); -DECLARE_SOA_COLUMN(PhotonY, photonY, float); -DECLARE_SOA_COLUMN(PhotonPhi, photonPhi, float); DECLARE_SOA_COLUMN(PhotonPosTPCNSigmaEl, photonPosTPCNSigmaEl, float); DECLARE_SOA_COLUMN(PhotonNegTPCNSigmaEl, photonNegTPCNSigmaEl, float); -DECLARE_SOA_COLUMN(PhotonPosTPCNSigmaPi, photonPosTPCNSigmaPi, float); -DECLARE_SOA_COLUMN(PhotonNegTPCNSigmaPi, photonNegTPCNSigmaPi, float); DECLARE_SOA_COLUMN(PhotonPosTPCCrossedRows, photonPosTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(PhotonNegTPCCrossedRows, photonNegTPCCrossedRows, uint8_t); -DECLARE_SOA_COLUMN(PhotonPosPt, photonPosPt, float); -DECLARE_SOA_COLUMN(PhotonNegPt, photonNegPt, float); DECLARE_SOA_COLUMN(PhotonPosEta, photonPosEta, float); DECLARE_SOA_COLUMN(PhotonNegEta, photonNegEta, float); -DECLARE_SOA_COLUMN(PhotonPosY, photonPosY, float); -DECLARE_SOA_COLUMN(PhotonNegY, photonNegY, float); DECLARE_SOA_COLUMN(PhotonPsiPair, photonPsiPair, float); DECLARE_SOA_COLUMN(PhotonPosITSCls, photonPosITSCls, int); DECLARE_SOA_COLUMN(PhotonNegITSCls, photonNegITSCls, int); @@ -84,52 +213,36 @@ DECLARE_SOA_COLUMN(PhotonNegITSChi2PerNcl, photonNegITSChi2PerNcl, float); DECLARE_SOA_COLUMN(PhotonPosTrackCode, photonPosTrackCode, uint8_t); DECLARE_SOA_COLUMN(PhotonNegTrackCode, photonNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(PhotonV0Type, photonV0Type, uint8_t); -DECLARE_SOA_COLUMN(GammaBDTScore, gammaBDTScore, float); - -} // namespace sigmaPhotonExtra - -DECLARE_SOA_TABLE(SigmaPhotonExtras, "AOD", "SIGMA0PHOTON", - sigmaPhotonExtra::PhotonPt, - sigmaPhotonExtra::PhotonMass, - sigmaPhotonExtra::PhotonQt, - sigmaPhotonExtra::PhotonAlpha, - sigmaPhotonExtra::PhotonRadius, - sigmaPhotonExtra::PhotonCosPA, - sigmaPhotonExtra::PhotonDCADau, - sigmaPhotonExtra::PhotonDCANegPV, - sigmaPhotonExtra::PhotonDCAPosPV, - sigmaPhotonExtra::PhotonZconv, - sigmaPhotonExtra::PhotonEta, - sigmaPhotonExtra::PhotonY, - sigmaPhotonExtra::PhotonPhi, - sigmaPhotonExtra::PhotonPosTPCNSigmaEl, - sigmaPhotonExtra::PhotonNegTPCNSigmaEl, - sigmaPhotonExtra::PhotonPosTPCNSigmaPi, - sigmaPhotonExtra::PhotonNegTPCNSigmaPi, - sigmaPhotonExtra::PhotonPosTPCCrossedRows, - sigmaPhotonExtra::PhotonNegTPCCrossedRows, - sigmaPhotonExtra::PhotonPosPt, - sigmaPhotonExtra::PhotonNegPt, - sigmaPhotonExtra::PhotonPosEta, - sigmaPhotonExtra::PhotonNegEta, - sigmaPhotonExtra::PhotonPosY, - sigmaPhotonExtra::PhotonNegY, - sigmaPhotonExtra::PhotonPsiPair, - sigmaPhotonExtra::PhotonPosITSCls, - sigmaPhotonExtra::PhotonNegITSCls, - sigmaPhotonExtra::PhotonPosITSChi2PerNcl, - sigmaPhotonExtra::PhotonNegITSChi2PerNcl, - sigmaPhotonExtra::PhotonPosTrackCode, - sigmaPhotonExtra::PhotonNegTrackCode, - sigmaPhotonExtra::PhotonV0Type, - sigmaPhotonExtra::GammaBDTScore); + +} // namespace sigma0PhotonExtra + +DECLARE_SOA_TABLE(Sigma0PhotonExtras, "AOD", "SIGMA0PHOTON", + sigma0PhotonExtra::PhotonQt, + sigma0PhotonExtra::PhotonAlpha, + sigma0PhotonExtra::PhotonCosPA, + sigma0PhotonExtra::PhotonDCADau, + sigma0PhotonExtra::PhotonDCANegPV, + sigma0PhotonExtra::PhotonDCAPosPV, + sigma0PhotonExtra::PhotonRadius, + sigma0PhotonExtra::PhotonZconv, + sigma0PhotonExtra::PhotonPosTPCNSigmaEl, + sigma0PhotonExtra::PhotonNegTPCNSigmaEl, + sigma0PhotonExtra::PhotonPosTPCCrossedRows, + sigma0PhotonExtra::PhotonNegTPCCrossedRows, + sigma0PhotonExtra::PhotonPosEta, + sigma0PhotonExtra::PhotonNegEta, + sigma0PhotonExtra::PhotonPsiPair, + sigma0PhotonExtra::PhotonPosITSCls, + sigma0PhotonExtra::PhotonNegITSCls, + sigma0PhotonExtra::PhotonPosITSChi2PerNcl, + sigma0PhotonExtra::PhotonNegITSChi2PerNcl, + sigma0PhotonExtra::PhotonPosTrackCode, + sigma0PhotonExtra::PhotonNegTrackCode, + sigma0PhotonExtra::PhotonV0Type); // For Lambda extra info -namespace sigmaLambdaExtra +namespace sigma0LambdaExtra { -DECLARE_SOA_COLUMN(LambdaPt, lambdaPt, float); -DECLARE_SOA_COLUMN(LambdaMass, lambdaMass, float); -DECLARE_SOA_COLUMN(AntiLambdaMass, antilambdaMass, float); DECLARE_SOA_COLUMN(LambdaQt, lambdaQt, float); DECLARE_SOA_COLUMN(LambdaAlpha, lambdaAlpha, float); DECLARE_SOA_COLUMN(LambdaLifeTime, lambdaLifeTime, float); @@ -138,9 +251,6 @@ DECLARE_SOA_COLUMN(LambdaCosPA, lambdaCosPA, float); DECLARE_SOA_COLUMN(LambdaDCADau, lambdaDCADau, float); DECLARE_SOA_COLUMN(LambdaDCANegPV, lambdaDCANegPV, float); DECLARE_SOA_COLUMN(LambdaDCAPosPV, lambdaDCAPosPV, float); -DECLARE_SOA_COLUMN(LambdaEta, lambdaEta, float); -DECLARE_SOA_COLUMN(LambdaY, lambdaY, float); -DECLARE_SOA_COLUMN(LambdaPhi, lambdaPhi, float); DECLARE_SOA_COLUMN(LambdaPosPrTPCNSigma, lambdaPosPrTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaPosPiTPCNSigma, lambdaPosPiTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaNegPrTPCNSigma, lambdaNegPrTPCNSigma, float); @@ -151,14 +261,8 @@ DECLARE_SOA_COLUMN(ALambdaPrTOFNSigma, aLambdaPrTOFNSigma, float); DECLARE_SOA_COLUMN(ALambdaPiTOFNSigma, aLambdaPiTOFNSigma, float); DECLARE_SOA_COLUMN(LambdaPosTPCCrossedRows, lambdaPosTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(LambdaNegTPCCrossedRows, lambdaNegTPCCrossedRows, uint8_t); -DECLARE_SOA_COLUMN(LambdaPosPt, lambdaPosPt, float); -DECLARE_SOA_COLUMN(LambdaNegPt, lambdaNegPt, float); DECLARE_SOA_COLUMN(LambdaPosEta, lambdaPosEta, float); DECLARE_SOA_COLUMN(LambdaNegEta, lambdaNegEta, float); -DECLARE_SOA_COLUMN(LambdaPosPrY, lambdaPosPrY, float); -DECLARE_SOA_COLUMN(LambdaPosPiY, lambdaPosPiY, float); -DECLARE_SOA_COLUMN(LambdaNegPrY, lambdaNegPrY, float); -DECLARE_SOA_COLUMN(LambdaNegPiY, lambdaNegPiY, float); DECLARE_SOA_COLUMN(LambdaPosITSCls, lambdaPosITSCls, int); DECLARE_SOA_COLUMN(LambdaNegITSCls, lambdaNegITSCls, int); DECLARE_SOA_COLUMN(LambdaPosITSChi2PerNcl, lambdaPosChi2PerNcl, float); @@ -166,87 +270,587 @@ DECLARE_SOA_COLUMN(LambdaNegITSChi2PerNcl, lambdaNegChi2PerNcl, float); DECLARE_SOA_COLUMN(LambdaPosTrackCode, lambdaPosTrackCode, uint8_t); DECLARE_SOA_COLUMN(LambdaNegTrackCode, lambdaNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(LambdaV0Type, lambdaV0Type, uint8_t); -DECLARE_SOA_COLUMN(LambdaBDTScore, lambdaBDTScore, float); -DECLARE_SOA_COLUMN(AntiLambdaBDTScore, antilambdaBDTScore, float); - -} // namespace sigmaLambdaExtra - -DECLARE_SOA_TABLE(SigmaLambdaExtras, "AOD", "SIGMA0LAMBDA", - sigmaLambdaExtra::LambdaPt, - sigmaLambdaExtra::LambdaMass, - sigmaLambdaExtra::AntiLambdaMass, - sigmaLambdaExtra::LambdaQt, - sigmaLambdaExtra::LambdaAlpha, - sigmaLambdaExtra::LambdaLifeTime, - sigmaLambdaExtra::LambdaRadius, - sigmaLambdaExtra::LambdaCosPA, - sigmaLambdaExtra::LambdaDCADau, - sigmaLambdaExtra::LambdaDCANegPV, - sigmaLambdaExtra::LambdaDCAPosPV, - sigmaLambdaExtra::LambdaEta, - sigmaLambdaExtra::LambdaY, - sigmaLambdaExtra::LambdaPhi, - sigmaLambdaExtra::LambdaPosPrTPCNSigma, - sigmaLambdaExtra::LambdaPosPiTPCNSigma, - sigmaLambdaExtra::LambdaNegPrTPCNSigma, - sigmaLambdaExtra::LambdaNegPiTPCNSigma, - sigmaLambdaExtra::LambdaPrTOFNSigma, - sigmaLambdaExtra::LambdaPiTOFNSigma, - sigmaLambdaExtra::ALambdaPrTOFNSigma, - sigmaLambdaExtra::ALambdaPiTOFNSigma, - sigmaLambdaExtra::LambdaPosTPCCrossedRows, - sigmaLambdaExtra::LambdaNegTPCCrossedRows, - sigmaLambdaExtra::LambdaPosPt, - sigmaLambdaExtra::LambdaNegPt, - sigmaLambdaExtra::LambdaPosEta, - sigmaLambdaExtra::LambdaNegEta, - sigmaLambdaExtra::LambdaPosPrY, - sigmaLambdaExtra::LambdaPosPiY, - sigmaLambdaExtra::LambdaNegPrY, - sigmaLambdaExtra::LambdaNegPiY, - sigmaLambdaExtra::LambdaPosITSCls, - sigmaLambdaExtra::LambdaNegITSCls, - sigmaLambdaExtra::LambdaPosITSChi2PerNcl, - sigmaLambdaExtra::LambdaNegITSChi2PerNcl, - sigmaLambdaExtra::LambdaPosTrackCode, - sigmaLambdaExtra::LambdaNegTrackCode, - sigmaLambdaExtra::LambdaV0Type, - sigmaLambdaExtra::LambdaBDTScore, - sigmaLambdaExtra::AntiLambdaBDTScore); - -// for MC data -namespace sigmaMCCore + +} // namespace sigma0LambdaExtra + +DECLARE_SOA_TABLE(Sigma0LambdaExtras, "AOD", "SIGMA0LAMBDA", + sigma0LambdaExtra::LambdaQt, + sigma0LambdaExtra::LambdaAlpha, + sigma0LambdaExtra::LambdaLifeTime, + sigma0LambdaExtra::LambdaRadius, + sigma0LambdaExtra::LambdaCosPA, + sigma0LambdaExtra::LambdaDCADau, + sigma0LambdaExtra::LambdaDCANegPV, + sigma0LambdaExtra::LambdaDCAPosPV, + sigma0LambdaExtra::LambdaPosPrTPCNSigma, + sigma0LambdaExtra::LambdaPosPiTPCNSigma, + sigma0LambdaExtra::LambdaNegPrTPCNSigma, + sigma0LambdaExtra::LambdaNegPiTPCNSigma, + sigma0LambdaExtra::LambdaPrTOFNSigma, + sigma0LambdaExtra::LambdaPiTOFNSigma, + sigma0LambdaExtra::ALambdaPrTOFNSigma, + sigma0LambdaExtra::ALambdaPiTOFNSigma, + sigma0LambdaExtra::LambdaPosTPCCrossedRows, + sigma0LambdaExtra::LambdaNegTPCCrossedRows, + sigma0LambdaExtra::LambdaPosEta, + sigma0LambdaExtra::LambdaNegEta, + sigma0LambdaExtra::LambdaPosITSCls, + sigma0LambdaExtra::LambdaNegITSCls, + sigma0LambdaExtra::LambdaPosITSChi2PerNcl, + sigma0LambdaExtra::LambdaNegITSChi2PerNcl, + sigma0LambdaExtra::LambdaPosTrackCode, + sigma0LambdaExtra::LambdaNegTrackCode, + sigma0LambdaExtra::LambdaV0Type); + +// for MC +namespace sigma0MCCore { -DECLARE_SOA_COLUMN(IsSigma, isSigma, bool); // TODO: include PDG + IsPhysicalPrimary -DECLARE_SOA_COLUMN(IsAntiSigma, isAntiSigma, bool); -DECLARE_SOA_COLUMN(SigmaMCPt, sigmaMCPt, float); -DECLARE_SOA_COLUMN(PhotonCandPDGCode, photonCandPDGCode, int); -DECLARE_SOA_COLUMN(PhotonCandPDGCodeMother, photonCandPDGCodeMother, int); -DECLARE_SOA_COLUMN(IsPhotonCandPrimary, isPhotonCandPrimary, bool); -DECLARE_SOA_COLUMN(PhotonMCPt, photonMCPt, float); +DECLARE_SOA_COLUMN(MCradius, mcradius, float); +DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); +DECLARE_SOA_COLUMN(PDGCodeMother, pdgCodeMother, int); +DECLARE_SOA_COLUMN(MCprocess, mcprocess, int); +DECLARE_SOA_COLUMN(IsProducedByGenerator, isProducedByGenerator, bool); + +DECLARE_SOA_COLUMN(PhotonMCPx, photonmcpx, float); +DECLARE_SOA_COLUMN(PhotonMCPy, photonmcpy, float); +DECLARE_SOA_COLUMN(PhotonMCPz, photonmcpz, float); +DECLARE_SOA_COLUMN(IsPhotonPrimary, isPhotonPrimary, bool); +DECLARE_SOA_COLUMN(PhotonPDGCode, photonPDGCode, int); +DECLARE_SOA_COLUMN(PhotonPDGCodeMother, photonPDGCodeMother, int); DECLARE_SOA_COLUMN(PhotonIsCorrectlyAssoc, photonIsCorrectlyAssoc, bool); -DECLARE_SOA_COLUMN(LambdaCandPDGCode, lambdaCandPDGCode, int); -DECLARE_SOA_COLUMN(LambdaCandPDGCodeMother, lambdaCandPDGCodeMother, int); -DECLARE_SOA_COLUMN(IsLambdaCandPrimary, isLambdaCandPrimary, bool); -DECLARE_SOA_COLUMN(LambdaMCPt, lambdaMCPt, float); + +DECLARE_SOA_COLUMN(LambdaMCPx, lambdamcpx, float); +DECLARE_SOA_COLUMN(LambdaMCPy, lambdamcpy, float); +DECLARE_SOA_COLUMN(LambdaMCPz, lambdamcpz, float); +DECLARE_SOA_COLUMN(IsLambdaPrimary, isLambdaPrimary, bool); +DECLARE_SOA_COLUMN(LambdaPDGCode, lambdaPDGCode, int); +DECLARE_SOA_COLUMN(LambdaPDGCodeMother, lambdaPDGCodeMother, int); DECLARE_SOA_COLUMN(LambdaIsCorrectlyAssoc, lambdaIsCorrectlyAssoc, bool); -} // namespace sigmaMCCore - -DECLARE_SOA_TABLE(SigmaMCCores, "AOD", "SIGMA0MCCORES", - sigmaMCCore::IsSigma, - sigmaMCCore::IsAntiSigma, - sigmaMCCore::SigmaMCPt, - sigmaMCCore::PhotonCandPDGCode, - sigmaMCCore::PhotonCandPDGCodeMother, - sigmaMCCore::IsPhotonCandPrimary, - sigmaMCCore::PhotonMCPt, - sigmaMCCore::PhotonIsCorrectlyAssoc, - sigmaMCCore::LambdaCandPDGCode, - sigmaMCCore::LambdaCandPDGCodeMother, - sigmaMCCore::IsLambdaCandPrimary, - sigmaMCCore::LambdaMCPt, - sigmaMCCore::LambdaIsCorrectlyAssoc); +DECLARE_SOA_DYNAMIC_COLUMN(IsSigma0, isSigma0, //! IsSigma0 + [](int pdgCode) -> bool { return pdgCode == 3212; }); + +DECLARE_SOA_DYNAMIC_COLUMN(IsAntiSigma0, isAntiSigma0, //! IsASigma0 + [](int pdgCode) -> bool { return pdgCode == -3212; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPx, mcpx, //! Sigma0 px + [](float photonMCPx, float lambdaMCPx) -> float { return photonMCPx + lambdaMCPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPy, mcpy, //! Sigma0 py + [](float photonMCPy, float lambdaMCPy) -> float { return photonMCPy + lambdaMCPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPz, mcpz, //! Sigma0 pz + [](float photonMCPz, float lambdaMCPz) -> float { return photonMCPz + lambdaMCPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPt, mcpt, + [](float photonMCPx, float photonMCPy, float lambdaMCPx, float lambdaMCPy) -> float { + return RecoDecay::pt(array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCP, mcp, //! Total momentum in GeV/c + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0MCMass, sigma0MCMass, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + std::array pVecPhotons{photonMCPx, photonMCPy, photonMCPz}; + std::array pVecLambda{lambdaMCPx, lambdaMCPy, lambdaMCPz}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Sigma0MCY, sigma0MCY, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::y(std::array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz}, o2::constants::physics::MassSigma0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPhi, mcphi, //! Phi in the range [0, 2pi) + [](float photonMCPx, float photonMCPy, float lambdaMCPx, float lambdaMCPy) -> float { return RecoDecay::phi(photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCEta, mceta, //! Pseudorapidity + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::eta(std::array{photonMCPx + lambdaMCPx, photonMCPy + lambdaMCPy, photonMCPz + lambdaMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCOPAngle, mcopAngle, + [](float photonMCPx, float photonMCPy, float photonMCPz, float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) { + TVector3 v1(photonMCPx, photonMCPy, photonMCPz); + TVector3 v2(lambdaMCPx, lambdaMCPy, lambdaMCPz); + return v1.Angle(v2); + }); + +// Photon +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCPt, photonmcpt, //! Transverse momentum in GeV/c + [](float photonMCPx, float photonMCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx, photonMCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCP, photonmcp, //! Total momentum in GeV/c + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photonMCPx, photonMCPy, photonMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCEta, photonMCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::eta(std::array{photonMCPx, photonMCPy, photonMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCY, photonMCY, //! Rapidity + [](float photonMCPx, float photonMCPy, float photonMCPz) -> float { + return RecoDecay::y(std::array{photonMCPx, photonMCPy, photonMCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(PhotonMCPhi, photonMCPhi, //! Phi in the range [0, 2pi) + [](float photonMCPx, float photonMCPy) -> float { return RecoDecay::phi(photonMCPx, photonMCPy); }); + +// Lambda/ALambda +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCPt, lambdamcpt, //! Transverse momentum in GeV/c + [](float lambdaMCPx, float lambdaMCPy) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaMCPx, lambdaMCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCP, lambdamcp, //! Total momentum in GeV/c + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::sqrtSumOfSquares(lambdaMCPx, lambdaMCPy, lambdaMCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCEta, lambdaMCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::eta(std::array{lambdaMCPx, lambdaMCPy, lambdaMCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCY, lambdaMCY, //! Rapidity + [](float lambdaMCPx, float lambdaMCPy, float lambdaMCPz) -> float { + return RecoDecay::y(std::array{lambdaMCPx, lambdaMCPy, lambdaMCPz}, o2::constants::physics::MassLambda); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(LambdaMCPhi, lambdaMCPhi, //! Phi in the range [0, 2pi) + [](float lambdaMCPx, float lambdaMCPy) -> float { return RecoDecay::phi(lambdaMCPx, lambdaMCPy); }); + +} // namespace sigma0MCCore + +DECLARE_SOA_TABLE(Sigma0MCCores, "AOD", "SIGMA0MCCORES", + // Basic properties + sigma0MCCore::MCradius, sigma0MCCore::PDGCode, sigma0MCCore::PDGCodeMother, sigma0MCCore::MCprocess, sigma0MCCore::IsProducedByGenerator, + + sigma0MCCore::PhotonMCPx, sigma0MCCore::PhotonMCPy, sigma0MCCore::PhotonMCPz, + sigma0MCCore::IsPhotonPrimary, sigma0MCCore::PhotonPDGCode, sigma0MCCore::PhotonPDGCodeMother, sigma0MCCore::PhotonIsCorrectlyAssoc, + + sigma0MCCore::LambdaMCPx, sigma0MCCore::LambdaMCPy, sigma0MCCore::LambdaMCPz, + sigma0MCCore::IsLambdaPrimary, sigma0MCCore::LambdaPDGCode, sigma0MCCore::LambdaPDGCodeMother, sigma0MCCore::LambdaIsCorrectlyAssoc, + + // Dynamic columns + sigma0MCCore::IsSigma0, + sigma0MCCore::IsAntiSigma0, + + sigma0MCCore::MCPx, + sigma0MCCore::MCPy, + sigma0MCCore::MCPz, + sigma0MCCore::MCPt, + sigma0MCCore::MCP, + sigma0MCCore::Sigma0MCMass, + sigma0MCCore::Sigma0MCY, + sigma0MCCore::MCPhi, + sigma0MCCore::MCEta, + sigma0MCCore::MCOPAngle, + + sigma0MCCore::PhotonMCPt, + sigma0MCCore::PhotonMCP, + sigma0MCCore::PhotonMCEta, + sigma0MCCore::PhotonMCY, + sigma0MCCore::PhotonMCPhi, + + sigma0MCCore::LambdaMCPt, + sigma0MCCore::LambdaMCP, + sigma0MCCore::LambdaMCEta, + sigma0MCCore::LambdaMCY, + sigma0MCCore::LambdaMCPhi); + +namespace sigma0Gen +{ +DECLARE_SOA_COLUMN(IsSigma0, isSigma0, bool); // true: sigma0, false: antisigma0 +DECLARE_SOA_COLUMN(ProducedByGenerator, producedByGenerator, bool); +DECLARE_SOA_COLUMN(Sigma0MCPt, sigma0MCPt, float); // MC pT + +} // namespace sigma0Gen + +DECLARE_SOA_TABLE(Sigma0Gens, "AOD", "SIGMA0GENS", + sigma0Gen::IsSigma0, + sigma0Gen::ProducedByGenerator, + sigma0Gen::Sigma0MCPt); + +DECLARE_SOA_TABLE(SigmaCollRef, "AOD", "SIGMACOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraCollisionId); + +DECLARE_SOA_TABLE(SigmaGenCollRef, "AOD", "SIGMAGENCOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraMCCollisionId); + +// ___________________________________________________________________________ +// pi0 QA +namespace Pi0Core +{ + +DECLARE_SOA_COLUMN(X, x, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(Z, z, float); +DECLARE_SOA_COLUMN(DCADaughters, dcadaughters, float); +DECLARE_SOA_COLUMN(CosPA, cospa, float); + +DECLARE_SOA_COLUMN(Photon1Px, photon1Px, float); +DECLARE_SOA_COLUMN(Photon1Py, photon1Py, float); +DECLARE_SOA_COLUMN(Photon1Pz, photon1Pz, float); +DECLARE_SOA_COLUMN(Photon1Mass, photon1Mass, float); +DECLARE_SOA_COLUMN(Photon1Qt, photon1Qt, float); +DECLARE_SOA_COLUMN(Photon1Alpha, photon1Alpha, float); +DECLARE_SOA_COLUMN(Photon1DCAPosPV, photon1DCAPosPV, float); +DECLARE_SOA_COLUMN(Photon1DCANegPV, photon1DCANegPV, float); +DECLARE_SOA_COLUMN(Photon1DCADau, photon1DCADau, float); +DECLARE_SOA_COLUMN(Photon1NegEta, photon1NegEta, float); +DECLARE_SOA_COLUMN(Photon1PosEta, photon1PosEta, float); +DECLARE_SOA_COLUMN(Photon1CosPA, photon1CosPA, float); +DECLARE_SOA_COLUMN(Photon1Radius, photon1Radius, float); +DECLARE_SOA_COLUMN(Photon1Zconv, photon1Zconv, float); +DECLARE_SOA_COLUMN(Photon1PosTPCCrossedRows, photon1PosTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon1NegTPCCrossedRows, photon1NegTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon1PosTPCNSigmaEl, photon1PosTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon1NegTPCNSigmaEl, photon1NegTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon1V0Type, photon1V0Type, uint8_t); + +DECLARE_SOA_COLUMN(Photon2Px, photon2Px, float); +DECLARE_SOA_COLUMN(Photon2Py, photon2Py, float); +DECLARE_SOA_COLUMN(Photon2Pz, photon2Pz, float); +DECLARE_SOA_COLUMN(Photon2Mass, photon2Mass, float); +DECLARE_SOA_COLUMN(Photon2Qt, photon2Qt, float); +DECLARE_SOA_COLUMN(Photon2Alpha, photon2Alpha, float); +DECLARE_SOA_COLUMN(Photon2DCAPosPV, photon2DCAPosPV, float); +DECLARE_SOA_COLUMN(Photon2DCANegPV, photon2DCANegPV, float); +DECLARE_SOA_COLUMN(Photon2DCADau, photon2DCADau, float); +DECLARE_SOA_COLUMN(Photon2NegEta, photon2NegEta, float); +DECLARE_SOA_COLUMN(Photon2PosEta, photon2PosEta, float); +DECLARE_SOA_COLUMN(Photon2CosPA, photon2CosPA, float); +DECLARE_SOA_COLUMN(Photon2Radius, photon2Radius, float); +DECLARE_SOA_COLUMN(Photon2Zconv, photon2Zconv, float); +DECLARE_SOA_COLUMN(Photon2PosTPCCrossedRows, photon2PosTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon2NegTPCCrossedRows, photon2NegTPCCrossedRows, uint8_t); +DECLARE_SOA_COLUMN(Photon2PosTPCNSigmaEl, photon2PosTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon2NegTPCNSigmaEl, photon2NegTPCNSigmaEl, float); +DECLARE_SOA_COLUMN(Photon2V0Type, photon2V0Type, uint8_t); + +//______________________________________________________ +// DYNAMIC COLUMNS +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! Pi0 px + [](float photon1Px, float photon2Px) -> float { return photon1Px + photon2Px; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! Pi0 py + [](float photon1Py, float photon2Py) -> float { return photon1Py + photon2Py; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! Pi0 pz + [](float photon1Pz, float photon2Pz) -> float { return photon1Pz + photon2Pz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, + [](float photon1Px, float photon1Py, float photon2Px, float photon2Py) -> float { + return RecoDecay::pt(array{photon1Px + photon2Px, photon1Py + photon2Py}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Total momentum in GeV/c + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0Mass, pi0Mass, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + std::array pVecPhoton1{photon1Px, photon1Py, photon1Pz}; + std::array pVecPhoton2{photon2Px, photon2Py, photon2Pz}; + auto arrMom = std::array{pVecPhoton1, pVecPhoton2}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0Y, pi0Y, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::y(std::array{photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz}, o2::constants::physics::MassPi0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Phi in the range [0, 2pi) + [](float photon1Px, float photon1Py, float photon2Px, float photon2Py) -> float { return RecoDecay::phi(photon1Px + photon2Px, photon1Py + photon2Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Pseudorapidity + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::eta(std::array{photon1Px + photon2Px, photon1Py + photon2Py, photon1Pz + photon2Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Radius, radius, //! Pi0 decay radius (2D, centered at zero) + [](float x, float y) -> float { return RecoDecay::sqrtSumOfSquares(x, y); }); + +DECLARE_SOA_DYNAMIC_COLUMN(OPAngle, opAngle, + [](float photon1Px, float photon1Py, float photon1Pz, float photon2Px, float photon2Py, float photon2Pz) { + TVector3 v1(photon1Px, photon1Py, photon1Pz); + TVector3 v2(photon2Px, photon2Py, photon2Pz); + return v1.Angle(v2); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Pt, photon1Pt, //! Transverse momentum in GeV/c + [](float photon1Px, float photon1Py) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px, photon1Py); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1P, photon1p, //! Total momentum in GeV/c + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1Px, photon1Py, photon1Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Eta, photon1Eta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::eta(std::array{photon1Px, photon1Py, photon1Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Y, photon1Y, //! Rapidity + [](float photon1Px, float photon1Py, float photon1Pz) -> float { + return RecoDecay::y(std::array{photon1Px, photon1Py, photon1Pz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1Phi, photon1Phi, //! Phi in the range [0, 2pi) + [](float photon1Px, float photon1Py) -> float { return RecoDecay::phi(photon1Px, photon1Py); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Pt, photon2Pt, //! Transverse momentum in GeV/c + [](float photon2Px, float photon2Py) -> float { + return RecoDecay::sqrtSumOfSquares(photon2Px, photon2Py); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2P, photon2p, //! Total momentum in GeV/c + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::sqrtSumOfSquares(photon2Px, photon2Py, photon2Pz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Eta, photon2Eta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::eta(std::array{photon2Px, photon2Py, photon2Pz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Y, photon2Y, //! Rapidity + [](float photon2Px, float photon2Py, float photon2Pz) -> float { + return RecoDecay::y(std::array{photon2Px, photon2Py, photon2Pz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2Phi, photon2Phi, //! Phi in the range [0, 2pi) + [](float photon2Px, float photon2Py) -> float { return RecoDecay::phi(photon2Px, photon2Py); }); + +} // namespace Pi0Core + +DECLARE_SOA_TABLE(Pi0Cores, "AOD", "PI0CORES", + Pi0Core::X, Pi0Core::Y, Pi0Core::Z, Pi0Core::DCADaughters, Pi0Core::CosPA, + + // Photon 1 base properties + Pi0Core::Photon1Px, Pi0Core::Photon1Py, Pi0Core::Photon1Pz, + Pi0Core::Photon1Mass, Pi0Core::Photon1Qt, Pi0Core::Photon1Alpha, Pi0Core::Photon1DCAPosPV, Pi0Core::Photon1DCANegPV, Pi0Core::Photon1DCADau, + Pi0Core::Photon1NegEta, Pi0Core::Photon1PosEta, Pi0Core::Photon1CosPA, Pi0Core::Photon1Radius, Pi0Core::Photon1Zconv, + Pi0Core::Photon1PosTPCCrossedRows, Pi0Core::Photon1NegTPCCrossedRows, Pi0Core::Photon1PosTPCNSigmaEl, Pi0Core::Photon1NegTPCNSigmaEl, Pi0Core::Photon1V0Type, + + // Photon 2 base properties + Pi0Core::Photon2Px, Pi0Core::Photon2Py, Pi0Core::Photon2Pz, + Pi0Core::Photon2Mass, Pi0Core::Photon2Qt, Pi0Core::Photon2Alpha, Pi0Core::Photon2DCAPosPV, Pi0Core::Photon2DCANegPV, Pi0Core::Photon2DCADau, + Pi0Core::Photon2NegEta, Pi0Core::Photon2PosEta, Pi0Core::Photon2CosPA, Pi0Core::Photon2Radius, Pi0Core::Photon2Zconv, + Pi0Core::Photon2PosTPCCrossedRows, Pi0Core::Photon2NegTPCCrossedRows, Pi0Core::Photon2PosTPCNSigmaEl, Pi0Core::Photon2NegTPCNSigmaEl, Pi0Core::Photon2V0Type, + + // Dynamic columns + Pi0Core::Px, + Pi0Core::Py, + Pi0Core::Pz, + Pi0Core::Pt, + Pi0Core::P, + Pi0Core::Pi0Mass, + Pi0Core::Pi0Y, + Pi0Core::Phi, + Pi0Core::Eta, + Pi0Core::Radius, + Pi0Core::OPAngle, + + Pi0Core::Photon1Pt, + Pi0Core::Photon1P, + Pi0Core::Photon1Eta, + Pi0Core::Photon1Y, + Pi0Core::Photon1Phi, + + Pi0Core::Photon2Pt, + Pi0Core::Photon2P, + Pi0Core::Photon2Eta, + Pi0Core::Photon2Y, + Pi0Core::Photon2Phi); + +// for MC +namespace Pi0CoreMC +{ + +DECLARE_SOA_COLUMN(MCradius, mcradius, float); +DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); +DECLARE_SOA_COLUMN(PDGCodeMother, pdgCodeMother, int); +DECLARE_SOA_COLUMN(MCprocess, mcprocess, int); +DECLARE_SOA_COLUMN(IsProducedByGenerator, isProducedByGenerator, bool); + +DECLARE_SOA_COLUMN(Photon1MCPx, photon1mcpx, float); +DECLARE_SOA_COLUMN(Photon1MCPy, photon1mcpy, float); +DECLARE_SOA_COLUMN(Photon1MCPz, photon1mcpz, float); +DECLARE_SOA_COLUMN(IsPhoton1Primary, isPhoton1Primary, bool); +DECLARE_SOA_COLUMN(Photon1PDGCode, photon1PDGCode, int); +DECLARE_SOA_COLUMN(Photon1PDGCodeMother, photon1PDGCodeMother, int); +DECLARE_SOA_COLUMN(Photon1IsCorrectlyAssoc, photon1IsCorrectlyAssoc, bool); + +DECLARE_SOA_COLUMN(Photon2MCPx, photon2mcpx, float); +DECLARE_SOA_COLUMN(Photon2MCPy, photon2mcpy, float); +DECLARE_SOA_COLUMN(Photon2MCPz, photon2mcpz, float); +DECLARE_SOA_COLUMN(IsPhoton2Primary, isPhoton2Primary, bool); +DECLARE_SOA_COLUMN(Photon2PDGCode, photon2PDGCode, int); +DECLARE_SOA_COLUMN(Photon2PDGCodeMother, photon2PDGCodeMother, int); +DECLARE_SOA_COLUMN(Photon2IsCorrectlyAssoc, photon2IsCorrectlyAssoc, bool); + +DECLARE_SOA_DYNAMIC_COLUMN(IsPi0, isPi0, //! IsPi0 + [](int pdgCode) -> bool { return pdgCode == 111; }); + +DECLARE_SOA_DYNAMIC_COLUMN(IsFromXi0, isFromXi0, //! Pi0 from Xi0 + [](int pdgCodeMother) -> bool { return pdgCodeMother == 3322; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPx, mcpx, //! Pi0 MC px + [](float photon1MCPx, float photon2MCPx) -> float { return photon1MCPx + photon2MCPx; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPy, mcpy, //! Pi0 MC py + [](float photon1MCPy, float photon2MCPy) -> float { return photon1MCPy + photon2MCPy; }); +DECLARE_SOA_DYNAMIC_COLUMN(MCPz, mcpz, //! Pi0 MC pz + [](float photon1MCPz, float photon2MCPz) -> float { return photon1MCPz + photon2MCPz; }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPt, mcpt, + [](float photon1MCPx, float photon1MCPy, float photon2MCPx, float photon2MCPy) -> float { + return RecoDecay::pt(array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCP, mcp, //! Total momentum in GeV/c + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0MCMass, pi0MCMass, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + std::array pVecPhoton1{photon1MCPx, photon1MCPy, photon1MCPz}; + std::array pVecPhoton2{photon2MCPx, photon2MCPy, photon2MCPz}; + auto arrMom = std::array{pVecPhoton1, pVecPhoton2}; + return RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Pi0MCY, pi0MCY, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::y(std::array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz}, o2::constants::physics::MassPi0); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCPhi, mcphi, //! Phi in the range [0, 2pi) + [](float photon1MCPx, float photon1MCPy, float photon2MCPx, float photon2MCPy) -> float { return RecoDecay::phi(photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCEta, mceta, //! Pseudorapidity + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::eta(std::array{photon1MCPx + photon2MCPx, photon1MCPy + photon2MCPy, photon1MCPz + photon2MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(MCOPAngle, mcopAngle, + [](float photon1MCPx, float photon1MCPy, float photon1MCPz, float photon2MCPx, float photon2MCPy, float photon2MCPz) { + TVector3 v1(photon1MCPx, photon1MCPy, photon1MCPz); + TVector3 v2(photon2MCPx, photon2MCPy, photon2MCPz); + return v1.Angle(v2); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCPt, photon1MCPt, //! Transverse momentum in GeV/c + [](float photon1MCPx, float photon1MCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx, photon1MCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCP, photon1MCp, //! Total momentum in GeV/c + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon1MCPx, photon1MCPy, photon1MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCEta, photon1MCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::eta(std::array{photon1MCPx, photon1MCPy, photon1MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCY, photon1MCY, //! Rapidity + [](float photon1MCPx, float photon1MCPy, float photon1MCPz) -> float { + return RecoDecay::y(std::array{photon1MCPx, photon1MCPy, photon1MCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon1MCPhi, photon1MCPhi, //! Phi in the range [0, 2pi) + [](float photon1MCPx, float photon1MCPy) -> float { return RecoDecay::phi(photon1MCPx, photon1MCPy); }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCPt, photon2MCPt, //! Transverse momentum in GeV/c + [](float photon2MCPx, float photon2MCPy) -> float { + return RecoDecay::sqrtSumOfSquares(photon2MCPx, photon2MCPy); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCP, photon2MCp, //! Total momentum in GeV/c + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::sqrtSumOfSquares(photon2MCPx, photon2MCPy, photon2MCPz); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCEta, photon2MCEta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::eta(std::array{photon2MCPx, photon2MCPy, photon2MCPz}); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCY, photon2MCY, //! Rapidity + [](float photon2MCPx, float photon2MCPy, float photon2MCPz) -> float { + return RecoDecay::y(std::array{photon2MCPx, photon2MCPy, photon2MCPz}, o2::constants::physics::MassGamma); + }); + +DECLARE_SOA_DYNAMIC_COLUMN(Photon2MCPhi, photon2MCPhi, //! Phi in the range [0, 2pi) + [](float photon2MCPx, float photon2MCPy) -> float { return RecoDecay::phi(photon2MCPx, photon2MCPy); }); + +} // namespace Pi0CoreMC + +DECLARE_SOA_TABLE(Pi0CoresMC, "AOD", "PI0CORESMC", + // Basic properties + Pi0CoreMC::MCradius, Pi0CoreMC::PDGCode, Pi0CoreMC::PDGCodeMother, Pi0CoreMC::MCprocess, Pi0CoreMC::IsProducedByGenerator, + + Pi0CoreMC::Photon1MCPx, Pi0CoreMC::Photon1MCPy, Pi0CoreMC::Photon1MCPz, + Pi0CoreMC::IsPhoton1Primary, Pi0CoreMC::Photon1PDGCode, Pi0CoreMC::Photon1PDGCodeMother, Pi0CoreMC::Photon1IsCorrectlyAssoc, + + Pi0CoreMC::Photon2MCPx, Pi0CoreMC::Photon2MCPy, Pi0CoreMC::Photon2MCPz, + Pi0CoreMC::IsPhoton2Primary, Pi0CoreMC::Photon2PDGCode, Pi0CoreMC::Photon2PDGCodeMother, Pi0CoreMC::Photon2IsCorrectlyAssoc, + + // Dynamic columns + Pi0CoreMC::IsPi0, + Pi0CoreMC::IsFromXi0, + + Pi0CoreMC::MCPx, + Pi0CoreMC::MCPy, + Pi0CoreMC::MCPz, + Pi0CoreMC::MCPt, + Pi0CoreMC::MCP, + Pi0CoreMC::Pi0MCMass, + Pi0CoreMC::Pi0MCY, + Pi0CoreMC::MCPhi, + Pi0CoreMC::MCEta, + Pi0CoreMC::MCOPAngle, + + Pi0CoreMC::Photon1MCPt, + Pi0CoreMC::Photon1MCP, + Pi0CoreMC::Photon1MCEta, + Pi0CoreMC::Photon1MCY, + Pi0CoreMC::Photon1MCPhi, + + Pi0CoreMC::Photon2MCPt, + Pi0CoreMC::Photon2MCP, + Pi0CoreMC::Photon2MCEta, + Pi0CoreMC::Photon2MCY, + Pi0CoreMC::Photon2MCPhi); + +DECLARE_SOA_TABLE(Pi0CollRef, "AOD", "PI0COLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraCollisionId); + +namespace pi0Gen +{ +DECLARE_SOA_COLUMN(ProducedByGenerator, producedByGenerator, bool); +DECLARE_SOA_COLUMN(Pi0MCPt, pi0MCPt, float); // MC pT +} // namespace pi0Gen + +DECLARE_SOA_TABLE(Pi0Gens, "AOD", "PI0GENS", + pi0Gen::ProducedByGenerator, + pi0Gen::Pi0MCPt); + +DECLARE_SOA_TABLE(Pi0GenCollRef, "AOD", "PI0GENCOLLREF", //! optional table to refer back to a collision + o2::soa::Index<>, v0data::StraMCCollisionId); + } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSIGMATABLES_H_ diff --git a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx index 32ed292dddd..511dc283ce3 100644 --- a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx @@ -20,61 +20,74 @@ // gianni.shigeru.setoue.liveraro@cern.ch // -#include -#include -#include -#include +#include "PWGLF/DataModel/LFSigmaTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/CCDB/ctpRateFetcher.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFStrangenessMLTables.h" -#include "PWGLF/DataModel/LFSigmaTables.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "Math/Vector3D.h" +#include +#include #include #include -#include #include #include -#include +#include + +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using dauTracks = soa::Join; -using V0DerivedMCDatas = soa::Join; -using V0StandardDerivedDatas = soa::Join; +using V0StandardDerivedDatas = soa::Join; +using V0DerivedMCDatas = soa::Join; +using V0TOFStandardDerivedDatas = soa::Join; +using V0TOFDerivedMCDatas = soa::Join; struct sigma0builder { Service ccdb; ctpRateFetcher rateFetcher; - // SliceCache cache; - - Produces sigma0cores; // save sigma0 candidates for analysis - Produces sigmaPhotonExtras; // save sigma0 candidates for analysis - Produces sigmaLambdaExtras; // save sigma0 candidates for analysis - Produces sigma0mccores; - - // For manual sliceBy - // PresliceUnsorted perCollisionMCDerived = o2::aod::v0data::straCollisionId; - // PresliceUnsorted perCollisionSTDDerived = o2::aod::v0data::straCollisionId; - PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; - + //__________________________________________________ + // Sigma0 specific + Produces sigma0cores; // sigma0 candidates info for analysis + Produces sigmaPhotonExtras; // photons from sigma0 candidates info + Produces sigmaLambdaExtras; // lambdas from sigma0 candidates info + Produces sigma0CollRefs; // references collisions from Sigma0Cores + Produces sigma0mccores; // Reco sigma0 MC properties + Produces sigma0Gens; // Generated sigma0s + Produces sigma0GenCollRefs; // references collisions from sigma0Gens + + //__________________________________________________ + // Pi0 specific + Produces pi0cores; // pi0 candidates info for analysis + Produces pi0coresRefs; // references collisions from photonpair + Produces pi0coresmc; // Reco pi0 MC properties + Produces pi0Gens; // Generated pi0s + Produces pi0GenCollRefs; // references collisions from pi0Gens + + //__________________________________________________ // pack track quality but separte also afterburner // dynamic range: 0-31 enum selection : int { hasTPC = 0, @@ -86,48 +99,16 @@ struct sigma0builder { // Histogram registry HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; - Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study"}; - Configurable doPi0QA{"doPi0QA", true, "Flag to fill QA histos for pi0 rejection study."}; Configurable doAssocStudy{"doAssocStudy", false, "Do v0 to collision association study."}; - - // Event level Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; - struct : ConfigurableGroup { - Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; - Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; - Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; - Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; - Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; - Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; - Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; - Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; - Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; - Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; - Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; - Configurable requireNoCollInTimeRangeVzDep{"requireNoCollInTimeRangeVzDep", false, "reject collisions corrupted by the cannibalism, with other collisions with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ"}; - Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; - Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; - Configurable requireINEL0{"requireINEL0", false, "require INEL>0 event selection"}; - Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; - Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; - Configurable useEvtSelInDenomEff{"useEvtSelInDenomEff", false, "Consider event selections in the recoed <-> gen collision association for the denominator (or numerator) of the acc. x eff. (or signal loss)?"}; - Configurable applyZVtxSelOnMCPV{"applyZVtxSelOnMCPV", false, "Apply Z-vtx cut on the PV of the generated collision?"}; - Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; - // fast check on occupancy - Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; - Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; - - // fast check on interaction rate - Configurable minIR{"minIR", -1, "minimum IR collisions"}; - Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; - - } eventSelections; + // Tables to fill + Configurable fillPi0Tables{"fillPi0Tables", false, "fill pi0 tables for QA"}; + Configurable fillSigma0Tables{"fillSigma0Tables", true, "fill sigma0 tables for analysis"}; // For ML Selection Configurable useMLScores{"useMLScores", false, "use ML scores to select candidates"}; @@ -137,7 +118,7 @@ struct sigma0builder { // For standard approach: //// Lambda criteria: - Configurable V0Rapidity{"V0Rapidity", 0.8, "v0 rapidity"}; + Configurable V0Rapidity{"V0Rapidity", 0.5, "v0 rapidity"}; Configurable LambdaDauPseudoRap{"LambdaDauPseudoRap", 1.5, "Max pseudorapidity of daughter tracks"}; Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", 0.0, "min DCA Neg To PV (cm)"}; @@ -147,7 +128,7 @@ struct sigma0builder { Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 60, "Max V0 radius (cm)"}; Configurable LambdaWindow{"LambdaWindow", 0.05, "Mass window around expected (in GeV/c2)"}; - //// Photon criteria: + //// Photon criteria (for sigma0s and pi0s): Configurable PhotonMaxDauPseudoRap{"PhotonMaxDauPseudoRap", 1.5, "Max pseudorapidity of daughter tracks"}; Configurable PhotonMinDCAToPv{"PhotonMinDCAToPv", 0.0, "Min DCA daughter To PV (cm)"}; Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; @@ -159,18 +140,18 @@ struct sigma0builder { Configurable Sigma0Window{"Sigma0Window", 0.1, "Mass window around expected (in GeV/c2)"}; Configurable SigmaMaxRap{"SigmaMaxRap", 0.8, "Max sigma0 rapidity"}; - //// Extras: - Configurable Pi0PhotonMinDCADauToPv{"Pi0PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; - Configurable Pi0PhotonMaxDCAV0Dau{"Pi0PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; - Configurable Pi0PhotonMinTPCCrossedRows{"Pi0PhotonMinTPCCrossedRows", 0, "Min daughter TPC Crossed Rows"}; - Configurable Pi0PhotonMaxTPCNSigmas{"Pi0PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable Pi0PhotonMaxEta{"Pi0PhotonMaxEta", 0.8, "Max photon rapidity"}; - Configurable Pi0PhotonMinRadius{"Pi0PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; - Configurable Pi0PhotonMaxRadius{"Pi0PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; - Configurable Pi0PhotonMaxQt{"Pi0PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; - Configurable Pi0PhotonMaxAlpha{"Pi0PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; - Configurable Pi0PhotonMinV0cospa{"Pi0PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; - Configurable Pi0PhotonMaxMass{"Pi0PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + //// Pi0 criteria:: + Configurable Pi0MaxRap{"Pi0MaxRap", 0.8, "Max Pi0 Rapidity"}; + Configurable Pi0MassWindow{"Pi0MassWindow", 0.115, "Mass window around expected (in GeV/c2)"}; + + //// Generated particles criteria: + struct : ConfigurableGroup { + Configurable doQA{"doQA", true, "If True, fill QA histos"}; + Configurable mc_keepOnlyFromGenerator{"mc_keepOnlyFromGenerator", false, "Keep only mcparticles from the generator"}; + Configurable mc_keepOnlyFromTransport{"mc_keepOnlyFromTransport", false, "Keep only mcparticles from the transport code"}; + Configurable mc_selectMCProcess{"mc_selectMCProcess", -1, "Keep only mcparticles produced in the selected MC process"}; + Configurable mc_rapidityWindow{"mc_rapidityWindow", 0.5, "Max generated particle rapidity"}; + } genSelections; // Axis // base properties @@ -181,16 +162,8 @@ struct sigma0builder { ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; - ConfigurableAxis axisPi0Mass{"axisPi0Mass", {200, 0.08f, 0.18f}, "M_{#Pi^{0}}"}; ConfigurableAxis axisK0SMass{"axisK0SMass", {200, 0.4f, 0.6f}, "M_{K^{0}}"}; - // AP plot axes - ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; - ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; - - // Track quality axes - ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; - // topological variable QA axes ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisXY{"axisXY", {120, -120.0f, 120.0f}, "XY axis"}; @@ -199,47 +172,30 @@ struct sigma0builder { ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; ConfigurableAxis axisCandSel{"axisCandSel", {7, 0.5f, +7.5f}, "Candidate Selection"}; - ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; - ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {151, -10, 1500}, "Binning for the interaction rate (kHz)"}; - int nSigmaCandidates = 0; void init(InitContext const&) { + LOGF(info, "Initializing now: cross-checking correctness..."); + if (doprocessRealData + + doprocessRealDataWithTOF + + doprocessMonteCarlo + + doprocessMonteCarloWithTOF > + 1) { + LOGF(fatal, "You have enabled more than one process function. Please check your configuration! Aborting now."); + } + // setting CCDB service ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setFatalWhenNull(false); - // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); - if (doPPAnalysis) { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); - } else { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); - } - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Below min IR"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(20, "Above max IR"); - histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + histos.add("PhotonSel/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); + histos.add("PhotonSel/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); + histos.add("PhotonSel/h2dV0XY", "h2dV0XY", kTH2F, {axisXY, axisXY}); + histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Photon Mass Cut"); @@ -258,6 +214,8 @@ struct sigma0builder { histos.add("PhotonSel/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); histos.add("PhotonSel/h3dPhotonMass", "h3dPhotonMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); + histos.add("LambdaSel/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); + histos.add("LambdaSel/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); histos.add("LambdaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Lambda Mass Cut"); @@ -284,32 +242,9 @@ struct sigma0builder { histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Sigma Y Window"); // For selection: - histos.add("SigmaSel/h3dMassSigma0BeforeSel", "h3dMassSigma0BeforeSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("SigmaSel/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); - histos.add("SigmaSel/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{200, -0.09f, 0.11f}}); - histos.add("SigmaSel/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); histos.add("SigmaSel/hSigmaMassSelected", "hSigmaMassSelected", kTH1F, {axisSigmaMass}); - histos.add("SigmaSel/h3dMassSigma0AfterSel", "h3dMassSigma0AfterSel", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); - - if (fillQAhistos) { - histos.add("GeneralQA/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); - histos.add("GeneralQA/h3dMassSigma0VsDaupTs", "h3dMassSigma0VsDaupTs", kTH3F, {axisPt, axisPt, axisSigmaMass}); - histos.add("GeneralQA/h2dMassGammaVsK0SAfterMassSel", "h2dMassGammaVsK0SAfterMassSel", kTH2D, {axisPhotonMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassLambdaVsK0SAfterMassSel", "h2dMassLambdaVsK0SAfterMassSel", kTH2D, {axisLambdaMass, axisK0SMass}); - histos.add("GeneralQA/h2dMassGammaVsLambdaAfterMassSel", "h2dMassGammaVsLambdaAfterMassSel", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h2dV0XY", "h2dV0XY", kTH2F, {axisXY, axisXY}); - } - if (fGetIR) { - histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); - histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1F, {axisIRBinning}); - histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2F, {axisCentrality, axisIRBinning}); - } - - if (doAssocStudy && doprocessMonteCarlo) { + if (doAssocStudy && (doprocessMonteCarlo || doprocessMonteCarloWithTOF)) { histos.add("V0AssoQA/h2dIRVsPt_TrueGamma", "h2dIRVsPt_TrueGamma", kTH2F, {axisIRBinning, axisPt}); histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma", "h3dPAVsIRVsPt_TrueGamma", kTH3F, {axisPA, axisIRBinning, axisPt}); histos.add("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig", "h2dIRVsPt_TrueGamma_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); @@ -322,225 +257,236 @@ struct sigma0builder { } // MC - if (doprocessMonteCarlo) { - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma", "h2dPtVsCentralityBeforeSel_MCAssocGamma", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda", "h2dPtVsCentralityBeforeSel_MCAssocLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda", "h2dPtVsCentralityBeforeSel_MCAssocALambda", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0", "h2dPtVsCentralityBeforeSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0", "h2dPtVsCentralityBeforeSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", "h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", "h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0", "h2dPtVsCentralityAfterSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0", "h2dPtVsCentralityAfterSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); + if (doprocessMonteCarlo || doprocessMonteCarloWithTOF) { histos.add("MC/h2dGammaXYConversion", "h2dGammaXYConversion", kTH2F, {axisXY, axisXY}); + histos.add("MC/h2dPtVsCentrality_MCAssocGamma", "h2dPtVsCentrality_MCAssocGamma", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_MCAssocLambda", "h2dPtVsCentrality_MCAssocLambda", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_MCAssocALambda", "h2dPtVsCentrality_MCAssocALambda", kTH2D, {axisCentrality, axisPt}); } - // For background decomposition - if (fillBkgQAhistos && doprocessMonteCarlo) { - histos.add("BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("BkgStudy/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - } + if (doprocessGeneratedRun3 && genSelections.doQA) { - // For Pi0 QA - if (doPi0QA) { - histos.add("Pi0QA/h3dMassPi0BeforeSel_MCAssoc", "h3dMassPi0BeforeSel_MCAssoc", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0AfterSel_MCAssoc", "h3dMassPi0AfterSel_MCAssoc", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0BeforeSel_Candidates", "h3dMassPi0BeforeSel_Candidates", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - histos.add("Pi0QA/h3dMassPi0AfterSel_Candidates", "h3dMassPi0AfterSel_Candidates", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); - } + // Pi0s + histos.add("GenQA/hGenPi0", "hGenPi0", kTH1D, {axisPt}); + + auto hPrimaryPi0s = histos.add("GenQA/hPrimaryPi0s", "hPrimaryPi0s", kTH1D, {{2, -0.5f, 1.5f}}); + hPrimaryPi0s->GetXaxis()->SetBinLabel(1, "All Pi0s"); + hPrimaryPi0s->GetXaxis()->SetBinLabel(2, "Primary Pi0s"); + + histos.add("GenQA/h2dPi0MCSourceVsPDGMother", "h2dPi0MCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("GenQA/h2dPi0NDaughtersVsPDG", "h2dPi0NDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); + + auto h2DGenPi0TypeVsProducedByGen = histos.add("GenQA/h2DGenPi0TypeVsProducedByGen", "h2DGenPi0TypeVsProducedByGen", kTH2D, {{2, -0.5f, 1.5f}, {2, -0.5f, 1.5f}}); + h2DGenPi0TypeVsProducedByGen->GetXaxis()->SetBinLabel(1, "Sterile"); + h2DGenPi0TypeVsProducedByGen->GetXaxis()->SetBinLabel(2, "Non-Sterile"); + h2DGenPi0TypeVsProducedByGen->GetYaxis()->SetBinLabel(1, "Generator"); + h2DGenPi0TypeVsProducedByGen->GetYaxis()->SetBinLabel(2, "Transport"); + + // ______________________________________________________ + // Sigma0s + histos.add("GenQA/hGenSigma0", "hGenSigma0", kTH1D, {axisPt}); + histos.add("GenQA/hGenAntiSigma0", "hGenAntiSigma0", kTH1D, {axisPt}); + + histos.add("GenQA/h2dGenSigma0xy_Generator", "hGenSigma0xy_Generator", kTH2D, {axisXY, axisXY}); + histos.add("GenQA/h2dGenSigma0xy_Transport", "hGenSigma0xy_Transport", kTH2D, {axisXY, axisXY}); + histos.add("GenQA/hGenSigma0Radius_Generator", "hGenSigma0Radius_Generator", kTH1D, {axisRadius}); + histos.add("GenQA/hGenSigma0Radius_Transport", "hGenSigma0Radius_Transport", kTH1D, {axisRadius}); + + histos.add("GenQA/h2dSigma0MCSourceVsPDGMother", "h2dSigma0MCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("GenQA/h2dSigma0NDaughtersVsPDG", "h2dSigma0NDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); + + auto hPrimarySigma0s = histos.add("GenQA/hPrimarySigma0s", "hPrimarySigma0s", kTH1D, {{2, -0.5f, 1.5f}}); + hPrimarySigma0s->GetXaxis()->SetBinLabel(1, "All Sigma0s"); + hPrimarySigma0s->GetXaxis()->SetBinLabel(2, "Primary Sigma0s"); + + auto hGenSpecies = histos.add("GenQA/hGenSpecies", "hGenSpecies", kTH1D, {{4, -0.5f, 3.5f}}); + hGenSpecies->GetXaxis()->SetBinLabel(1, "All Prim. Lambda"); + hGenSpecies->GetXaxis()->SetBinLabel(2, "All Prim. ALambda"); + hGenSpecies->GetXaxis()->SetBinLabel(5, "All Sigma0s"); + hGenSpecies->GetXaxis()->SetBinLabel(6, "All ASigma0s"); - if (doprocessGeneratedRun3) { - - histos.add("Gen/hGenEvents", "hGenEvents", kTH2F, {{axisNch}, {2, -0.5f, +1.5f}}); - histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); - histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); - - histos.add("Gen/hGenEventCentrality", "hGenEventCentrality", kTH1F, {{101, 0.0f, 101.0f}}); - histos.add("Gen/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2F, {axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("Gen/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2F, {axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("Gen/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2F, {{101, 0.0f, 101.0f}, axisNch}); - histos.add("Gen/h2dGenGamma", "h2dGenGamma", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenLambda", "h2dGenLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenAntiLambda", "h2dGenAntiLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("Gen/h2dGenGammaVsMultMC_RecoedEvt", "h2dGenGammaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenLambdaVsMultMC_RecoedEvt", "h2dGenLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenAntiLambdaVsMultMC_RecoedEvt", "h2dGenAntiLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenGammaVsMultMC", "h2dGenGammaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenLambdaVsMultMC", "h2dGenLambdaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/h2dGenAntiLambdaVsMultMC", "h2dGenAntiLambdaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("Gen/hEventPVzMC", "hEventPVzMC", kTH1F, {{100, -20.0f, +20.0f}}); - histos.add("Gen/hCentralityVsPVzMC", "hCentralityVsPVzMC", kTH2F, {{101, 0.0f, 101.0f}, {100, -20.0f, +20.0f}}); - - auto hPrimaryV0s = histos.add("Gen/hPrimaryV0s", "hPrimaryV0s", kTH1D, {{2, -0.5f, 1.5f}}); - hPrimaryV0s->GetXaxis()->SetBinLabel(1, "All V0s"); - hPrimaryV0s->GetXaxis()->SetBinLabel(2, "Primary V0s"); + histos.add("GenQA/hSigma0NDau", "hSigma0NDau", kTH1D, {{10, -0.5f, +9.5f}}); + histos.add("GenQA/h2dSigma0NDauVsProcess", "h2dSigma0NDauVsProcess", kTH2D, {{10, -0.5f, +9.5f}, {50, -0.5f, 49.5f}}); + + auto h2DGenSigma0TypeVsProducedByGen = histos.add("GenQA/h2DGenSigma0TypeVsProducedByGen", "h2DGenSigma0TypeVsProducedByGen", kTH2D, {{2, -0.5f, 1.5f}, {2, -0.5f, 1.5f}}); + h2DGenSigma0TypeVsProducedByGen->GetXaxis()->SetBinLabel(1, "Sterile"); + h2DGenSigma0TypeVsProducedByGen->GetXaxis()->SetBinLabel(2, "Non-Sterile"); + h2DGenSigma0TypeVsProducedByGen->GetYaxis()->SetBinLabel(1, "Generator"); + h2DGenSigma0TypeVsProducedByGen->GetYaxis()->SetBinLabel(2, "Transport"); } } - template - bool IsEventAccepted(TCollision const& collision, bool fillHists) - // check whether the collision passes our collision selections + // ______________________________________________________ + // Struct to store V0Pair properties + struct V0PairTopoInfo { + float X = -999.f; + float Y = -999.f; + float Z = -999.f; + float DCADau = -999.f; + float CosPA = -1.f; + }; + + // ______________________________________________________ + // Struct to store V0Pair MC properties + struct V0PairMCInfo { + bool fIsV01CorrectlyAssign = false; + bool fIsV02CorrectlyAssign = false; + bool fIsV01Primary = false; + bool fIsV02Primary = false; + bool fV0PairProducedByGenerator = false; + int V01PDGCode = 0; + int V02PDGCode = 0; + int V01PDGCodeMother = 0; + int V02PDGCodeMother = 0; + int V0PairPDGCode = 0; + int V0PairPDGCodeMother = 0; + int V0PairMCProcess = -1; + int V0PairMCParticleID = -1; + float V01MCpx = -999.f; + float V01MCpy = -999.f; + float V01MCpz = -999.f; + float V02MCpx = -999.f; + float V02MCpy = -999.f; + float V02MCpz = -999.f; + float V0PairMCRadius = -999.f; + }; + + // ______________________________________________________ + // Struct to store V0Pair Generated properties + struct V0PairGenInfo { + bool IsPrimary = false; + bool IsV0Lambda = false; + bool IsV0AntiLambda = false; + bool IsPi0 = false; + bool IsSigma0 = false; + bool IsAntiSigma0 = false; + bool IsProducedByGenerator = false; + bool IsSterile = false; + int MCProcess = -1; + int MCCollId = -1; + int PDGCodeMother = 0; + int NDaughters = -1; + float MCPt = -999.f; + float MCvx = 999.f; + float MCvy = 999.f; + }; + + template + V0PairTopoInfo propagateV0PairToDCA(TV01 const& v01, TV02 const& v02) { - if (fillHists) - histos.fill(HIST("hEventSelection"), 0. /* all collisions */); - if (eventSelections.requireSel8 && !collision.sel8()) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); - if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); - if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); - if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); - if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); - if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); - if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); - if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); - if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); - if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); - if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); - if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); - if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); - if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); - if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); - if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); - } else { // we are in Pb-Pb - float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); - if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); - if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); - } - // Fetch interaction rate only if required (in order to limit ccdb calls) - double interactionRate = (eventSelections.minIR >= 0 || eventSelections.maxIR >= 0) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; - if (eventSelections.minIR >= 0 && interactionRate < eventSelections.minIR) { - return false; - } - if (fillHists) - histos.fill(HIST("hEventSelection"), 18 /* Below min IR */); + V0PairTopoInfo info; - if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { - return false; + // Positions + ROOT::Math::XYZVector v01position(v01.x(), v01.y(), v01.z()); + ROOT::Math::XYZVector v02position(v02.x(), v02.y(), v02.z()); + + // Momenta + ROOT::Math::XYZVector v01momentum(v01.px(), v01.py(), v01.pz()); + ROOT::Math::XYZVector v02momentum(v02.px(), v02.py(), v02.pz()); + + // Momenta (normalized) + ROOT::Math::XYZVector v01momentumNorm(v01.px() / v01.p(), v01.py() / v01.p(), v01.pz() / v01.p()); + ROOT::Math::XYZVector v02momentumNorm(v02.px() / v02.p(), v02.py() / v02.p(), v02.pz() / v02.p()); + + // DCADau calculation (using full momenta for precision) + ROOT::Math::XYZVector posdiff = v02position - v01position; + ROOT::Math::XYZVector cross = v01momentum.Cross(v02momentum); + + float d = 1.0f - TMath::Power(v01momentumNorm.Dot(v02momentumNorm), 2); + float t = posdiff.Dot(v01momentumNorm - v01momentumNorm.Dot(v02momentumNorm) * v02momentumNorm) / d; + float s = -posdiff.Dot(v02momentumNorm - v01momentumNorm.Dot(v02momentumNorm) * v01momentumNorm) / d; + + ROOT::Math::XYZVector pointOn1 = v01position + t * v01momentumNorm; + ROOT::Math::XYZVector pointOn2 = v02position + s * v02momentumNorm; + ROOT::Math::XYZVector PCA = 0.5 * (pointOn1 + pointOn2); + + // Calculate properties and fill struct + info.DCADau = (cross.Mag2() > 0) ? std::abs(posdiff.Dot(cross)) / cross.R() : 999.f; + info.CosPA = v01momentumNorm.Dot(v02momentumNorm); + + if (d < 1e-5f) { // Parallel or nearly parallel lines + info.X = info.Y = info.Z = 0.f; // should we use another dummy value? Perhaps 999.f? + return info; } - if (fillHists) - histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - histos.fill(HIST("hEventCentrality"), centrality); - return true; + info.X = PCA.X(); + info.Y = PCA.Y(); + info.Z = PCA.Z(); + + return info; } - void runBkgAnalysis(bool fIsSigma, bool fIsAntiSigma, int PhotonPDGCode, int PhotonPDGCodeMother, int LambdaPDGCode, int LambdaPDGCodeMother, float sigmapT, float sigmaMass) + template + V0PairMCInfo getV0PairMCInfo(TV01 const& v01, TV02 const& v02, TCollision const& collision, TMCParticles const& mcparticles) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); + V0PairMCInfo MCinfo; - // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! - if ((PhotonPDGCode == 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122)) && (!fIsSigma && !fIsAntiSigma)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueDaughters"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dTrueDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); - } + if (!v01.has_v0MCCore() || !v02.has_v0MCCore()) + return MCinfo; - // Real Gamma x fake Lambda - if ((PhotonPDGCode == 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dTrueGammaFakeLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); - } + auto v01MC = v01.template v0MCCore_as>(); + auto v02MC = v02.template v0MCCore_as>(); - // Fake Gamma x Real Lambda - if ((PhotonPDGCode != 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122))) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dFakeGammaTrueLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + if (collision.has_straMCCollision()) { + auto MCCollision = collision.template straMCCollision_as>(); + MCinfo.fIsV01CorrectlyAssign = (v01MC.straMCCollisionId() == MCCollision.globalIndex()); + MCinfo.fIsV02CorrectlyAssign = (v02MC.straMCCollisionId() == MCCollision.globalIndex()); } - // Fake Gamma x Fake Lambda - if ((PhotonPDGCode != 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { - histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); - histos.fill(HIST("BkgStudy/h2dFakeDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + MCinfo.V01MCpx = v01MC.pxMC(); + MCinfo.V01MCpy = v01MC.pyMC(); + MCinfo.V01MCpz = v01MC.pzMC(); + MCinfo.V02MCpx = v02MC.pxMC(); + MCinfo.V02MCpy = v02MC.pyMC(); + MCinfo.V02MCpz = v02MC.pzMC(); + + // Get corresponding entries in MCParticles table + auto MCParticle_v01 = mcparticles.rawIteratorAt(v01MC.particleIdMC()); + auto MCParticle_v02 = mcparticles.rawIteratorAt(v02MC.particleIdMC()); + + // Get MC Mothers + auto const& MCMothersList_v01 = MCParticle_v01.template mothers_as(); + auto const& MCMothersList_v02 = MCParticle_v02.template mothers_as(); + + if (!MCMothersList_v01.empty() && !MCMothersList_v02.empty()) { // Are there mothers? + + auto const& MCMother_v01 = MCMothersList_v01.front(); // First mother + auto const& MCMother_v02 = MCMothersList_v02.front(); // First mother + + if (MCMother_v01.globalIndex() == MCMother_v02.globalIndex()) { // Is it the same mother? + + MCinfo.fV0PairProducedByGenerator = MCMother_v01.producedByGenerator(); + MCinfo.V0PairPDGCode = MCMother_v01.pdgCode(); + MCinfo.V0PairMCProcess = MCMother_v01.getProcess(); + MCinfo.V0PairMCParticleID = MCMother_v01.globalIndex(); + MCinfo.V0PairMCRadius = std::hypot(MCMother_v01.vx(), MCMother_v01.vy()); // production position radius + + auto const& v0pairmothers = MCMother_v01.template mothers_as(); // Get mothers + if (!v0pairmothers.empty()) { + auto& v0PairMother = v0pairmothers.front(); // V0Pair mother, V0s grandmother + MCinfo.V0PairPDGCodeMother = v0PairMother.pdgCode(); + } + } } + + MCinfo.fIsV01Primary = v01MC.isPhysicalPrimary(); + MCinfo.fIsV02Primary = v02MC.isPhysicalPrimary(); + MCinfo.V01PDGCode = v01MC.pdgCode(); + MCinfo.V02PDGCode = v02MC.pdgCode(); + MCinfo.V01PDGCodeMother = v01MC.pdgCodeMother(); + MCinfo.V02PDGCodeMother = v02MC.pdgCodeMother(); + + return MCinfo; } + // ______________________________________________________ + // MC-specific + // Analyze v0-to-collision association template - void analyzeV0CollAssoc(TCollision const& collision, TV0Object const& fullv0s, std::vector selV0Indices, float IR, bool isPhotonAnalysis) + void analyzeV0CollAssoc(TCollision const& collision, TV0Object const& fullv0s, std::vector selV0Indices, bool isPhotonAnalysis) { auto v0MCCollision = collision.template straMCCollision_as>(); + float IR = (fGetIR) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; for (size_t i = 0; i < selV0Indices.size(); ++i) { auto v0 = fullv0s.rawIteratorAt(selV0Indices[i]); @@ -572,277 +518,179 @@ struct sigma0builder { } } - // ______________________________________________________ - // Simulated processing - // Return the list of indices to the recoed collision associated to a given MC collision. - template - std::vector getListOfRecoCollIndices(TMCollisions const& mcCollisions, TCollisions const& collisions) + template + V0PairGenInfo getV0PairGenInfo(TMCParticle const& mcParticle) { - std::vector listBestCollisionIdx(mcCollisions.size()); - for (auto const& mcCollision : mcCollisions) { - auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); - int biggestNContribs = -1; - int bestCollisionIndex = -1; - for (auto const& collision : groupedCollisions) { - // consider event selections in the recoed <-> gen collision association, for the denominator (or numerator) of the efficiency (or signal loss)? - if (eventSelections.useEvtSelInDenomEff) { - if (!IsEventAccepted(collision, false)) { - continue; - } - } - // Find the collision with the biggest nbr of PV contributors - // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 - if (biggestNContribs < collision.multPVTotalContributors()) { - biggestNContribs = collision.multPVTotalContributors(); - bestCollisionIndex = collision.globalIndex(); - } + V0PairGenInfo GenInfo; // auxiliary struct to store info + + // Fill with properties + GenInfo.IsPrimary = mcParticle.isPhysicalPrimary(); + GenInfo.IsV0Lambda = mcParticle.pdgCode() == 3122; + GenInfo.IsV0AntiLambda = mcParticle.pdgCode() == -3122; + GenInfo.IsPi0 = mcParticle.pdgCode() == 111; + GenInfo.IsSigma0 = mcParticle.pdgCode() == 3212; + GenInfo.IsAntiSigma0 = mcParticle.pdgCode() == -3212; + GenInfo.IsProducedByGenerator = mcParticle.producedByGenerator(); + GenInfo.MCProcess = mcParticle.getProcess(); + GenInfo.MCPt = mcParticle.pt(); + GenInfo.MCvx = mcParticle.vx(); // production position X + GenInfo.MCvy = mcParticle.vy(); // production position Y + + if (mcParticle.has_mcCollision()) + GenInfo.MCCollId = mcParticle.mcCollisionId(); // save this reference, please + + // Checking decay mode if sigma0 + if (GenInfo.IsSigma0 || GenInfo.IsAntiSigma0 || GenInfo.IsPi0) { + + // This is a costly operation, so we do it only for pi0s and sigma0s + auto const& daughters = mcParticle.template daughters_as(); + GenInfo.NDaughters = daughters.size(); + GenInfo.IsSterile = daughters.size() == 0; + + auto const& GenMothersList = mcParticle.template mothers_as(); + GenInfo.PDGCodeMother = (!GenMothersList.empty()) ? GenMothersList.front().pdgCode() : 0; + + if ((GenInfo.IsSigma0 || GenInfo.IsAntiSigma0) && genSelections.doQA) { + histos.fill(HIST("GenQA/h2dSigma0MCSourceVsPDGMother"), GenInfo.IsProducedByGenerator, GenInfo.PDGCodeMother); + for (auto& daughter : daughters) // checking decay modes + histos.fill(HIST("GenQA/h2dSigma0NDaughtersVsPDG"), daughters.size(), daughter.pdgCode()); + } + + if (GenInfo.IsPi0 && genSelections.doQA) { + histos.fill(HIST("GenQA/h2dPi0MCSourceVsPDGMother"), GenInfo.IsProducedByGenerator, GenInfo.PDGCodeMother); + for (auto& daughter : daughters) // checking decay modes + histos.fill(HIST("GenQA/h2dPi0NDaughtersVsPDG"), daughters.size(), daughter.pdgCode()); } - listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; } - return listBestCollisionIdx; + return GenInfo; } // ______________________________________________________ - // Simulated processing - // Fill generated event information (for event loss/splitting estimation) - template - void fillGeneratedEventProperties(TMCCollisions const& mcCollisions, TCollisions const& collisions) + // Simulated processing (subscribes to MC information too) + void fillGenQAHistos(V0PairGenInfo const& GenInfo) { - std::vector listBestCollisionIdx(mcCollisions.size()); - for (auto const& mcCollision : mcCollisions) { - // Apply selections on MC collisions - if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { - continue; + if (GenInfo.IsPi0) { + histos.fill(HIST("GenQA/hGenPi0"), GenInfo.MCPt); + histos.fill(HIST("GenQA/hPrimaryPi0s"), 0); + if (GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hPrimaryPi0s"), 1); + + if (GenInfo.IsSterile) { + if (GenInfo.IsProducedByGenerator) + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 0, 0); + else + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 0, 1); + } else { + if (GenInfo.IsProducedByGenerator) + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 1, 0); + else + histos.fill(HIST("GenQA/h2DGenPi0TypeVsProducedByGen"), 1, 1); } - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { - continue; - } + } - if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { - continue; - } + if (GenInfo.IsV0Lambda && GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hGenSpecies"), 0); + if (GenInfo.IsV0AntiLambda && GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hGenSpecies"), 1); + + // Checking decay mode + if (GenInfo.IsSigma0 || GenInfo.IsAntiSigma0) { + histos.fill(HIST("GenQA/hSigma0NDau"), GenInfo.NDaughters); + histos.fill(HIST("GenQA/h2dSigma0NDauVsProcess"), GenInfo.NDaughters, GenInfo.MCProcess); + + const auto radius = std::hypot(GenInfo.MCvx, GenInfo.MCvy); + // Sigma0 XY and radius (separate histos for Gen/Transport) + if (GenInfo.IsProducedByGenerator) { + histos.fill(HIST("GenQA/h2dGenSigma0xy_Generator"), GenInfo.MCvx, GenInfo.MCvy); + histos.fill(HIST("GenQA/hGenSigma0Radius_Generator"), radius); + } else { + histos.fill(HIST("GenQA/h2dGenSigma0xy_Transport"), GenInfo.MCvx, GenInfo.MCvy); + histos.fill(HIST("GenQA/hGenSigma0Radius_Transport"), radius); } - histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); - - auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); - // Check if there is at least one of the reconstructed collisions associated to this MC collision - // If so, we consider it - bool atLeastOne = false; - int biggestNContribs = -1; - float centrality = 100.5f; - int nCollisions = 0; - for (auto const& collision : groupedCollisions) { - - if (!IsEventAccepted(collision, false)) { - continue; - } + // Sigma0 type vs origin (single 2D histo) + const int genIndex = GenInfo.IsProducedByGenerator ? 0 : 1; // 0 = Generator, 1 = Transport + const int typeIndex = GenInfo.IsSterile ? 0 : 1; // 0 = Sterile, 1 = Normal + histos.fill(HIST("GenQA/h2DGenSigma0TypeVsProducedByGen"), typeIndex, genIndex); - if (biggestNContribs < collision.multPVTotalContributors()) { - biggestNContribs = collision.multPVTotalContributors(); - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - } + // Fill histograms + if (GenInfo.IsSigma0) { + histos.fill(HIST("GenQA/hGenSpecies"), 2); + histos.fill(HIST("GenQA/hGenSigma0"), GenInfo.MCPt); - nCollisions++; - atLeastOne = true; + histos.fill(HIST("GenQA/hPrimarySigma0s"), 0); + if (GenInfo.IsPrimary) + histos.fill(HIST("GenQA/hPrimarySigma0s"), 1); } - - histos.fill(HIST("Gen/hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); - histos.fill(HIST("Gen/hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); - histos.fill(HIST("Gen/hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); - histos.fill(HIST("Gen/hCentralityVsPVzMC"), centrality, mcCollision.posZ()); - histos.fill(HIST("Gen/hEventPVzMC"), mcCollision.posZ()); - - if (atLeastOne) { - histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); - histos.fill(HIST("Gen/hGenEventCentrality"), centrality); + if (GenInfo.IsAntiSigma0) { + histos.fill(HIST("GenQA/hGenSpecies"), 3); + histos.fill(HIST("GenQA/hGenAntiSigma0"), GenInfo.MCPt); } } - return; } // ______________________________________________________ // Simulated processing (subscribes to MC information too) - template - void analyzeGeneratedV0s(TMCCollisions const& mcCollisions, TV0MCs const& V0MCCores, TCollisions const& collisions) + template + void genProcess(TMCParticles const& mcParticles) { - fillGeneratedEventProperties(mcCollisions, collisions); - std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); - for (auto const& v0MC : V0MCCores) { - if (!v0MC.has_straMCCollision()) - continue; - - histos.fill(HIST("Gen/hPrimaryV0s"), 0); - if (!v0MC.isPhysicalPrimary()) + for (auto& mcParticle : mcParticles) { + // Rapidity selection + if (TMath::Abs(mcParticle.y()) > genSelections.mc_rapidityWindow) continue; - histos.fill(HIST("Gen/hPrimaryV0s"), 1); - - // TODO: get generated sigma0s - - float ptmc = v0MC.ptMC(); - float ymc = 1e3; - if (v0MC.pdgCode() == 22) - ymc = RecoDecay::y(std::array{v0MC.pxMC(), v0MC.pyMC(), v0MC.pzMC()}, o2::constants::physics::MassGamma); - - else if (std::abs(v0MC.pdgCode()) == 3122) - ymc = v0MC.rapidityMC(1); - - if (std::abs(ymc) > V0Rapidity) - continue; - - auto mcCollision = v0MC.template straMCCollision_as>(); - if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { - continue; - } - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { - continue; - } - - if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + // Selection on the source (generator/transport) + if (genSelections.mc_keepOnlyFromGenerator && !genSelections.mc_keepOnlyFromTransport) { + if (!mcParticle.producedByGenerator()) continue; - } } - float centrality = 100.5f; - if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { - auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); - - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("Gen/h2dGenGammaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == 3122) { - histos.fill(HIST("Gen/h2dGenLambdaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == -3122) { - histos.fill(HIST("Gen/h2dGenAntiLambdaVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); - } - } - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("Gen/h2dGenGamma"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenGammaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == 3122) { - histos.fill(HIST("Gen/h2dGenLambda"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenLambdaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); - } - if (v0MC.pdgCode() == -3122) { - histos.fill(HIST("Gen/h2dGenAntiLambda"), centrality, ptmc); - histos.fill(HIST("Gen/h2dGenAntiLambdaVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + if (genSelections.mc_keepOnlyFromTransport && !genSelections.mc_keepOnlyFromGenerator) { + if (mcParticle.producedByGenerator()) + continue; } - } - } - template - void runPi0QA(TV0Object const& gamma1, TV0Object const& gamma2, TCollision collision) - { - // Check if both V0s are made of the same tracks - if (gamma1.posTrackExtraId() == gamma2.posTrackExtraId() || - gamma1.negTrackExtraId() == gamma2.negTrackExtraId()) { - return; - } + // MC Process selection + if ((genSelections.mc_selectMCProcess >= 0) && (genSelections.mc_selectMCProcess != mcParticle.getProcess())) + continue; - // Calculate pi0 properties - std::array pVecGamma1{gamma1.px(), gamma1.py(), gamma1.pz()}; - std::array pVecGamma2{gamma2.px(), gamma2.py(), gamma2.pz()}; - std::array arrpi0{pVecGamma1, pVecGamma2}; - float pi0Mass = RecoDecay::m(arrpi0, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); - float pi0Pt = RecoDecay::pt(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py()}); - float pi0Y = RecoDecay::y(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py(), gamma1.pz() + gamma2.pz()}, o2::constants::physics::MassPi0); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + // Get generated particle info + auto MCGenInfo = getV0PairGenInfo(mcParticle); - // MC-specific variables - bool fIsPi0 = false, fIsMC = false; + // Fill QA histos + if (genSelections.doQA) + fillGenQAHistos(MCGenInfo); - // Check if MC data and populate fIsMC, fIsPi0 - if constexpr (requires { gamma1.motherMCPartId(); gamma2.motherMCPartId(); }) { - if (gamma1.has_v0MCCore() && gamma2.has_v0MCCore()) { - fIsMC = true; - auto gamma1MC = gamma1.template v0MCCore_as>(); - auto gamma2MC = gamma2.template v0MCCore_as>(); - - if (gamma1MC.pdgCode() == 22 && gamma2MC.pdgCode() == 22 && - gamma1MC.pdgCodeMother() == 111 && gamma2MC.pdgCodeMother() == 111 && - gamma1.motherMCPartId() == gamma2.motherMCPartId()) { - fIsPi0 = true; - histos.fill(HIST("Pi0QA/h3dMassPi0BeforeSel_MCAssoc"), centrality, pi0Pt, pi0Mass); - } + // Fill tables + // Pi0 + if (fillPi0Tables && MCGenInfo.IsPi0) { + pi0Gens(MCGenInfo.IsProducedByGenerator, MCGenInfo.MCPt); // optional table to store generated pi0 candidates. Be careful, this is a large table! + pi0GenCollRefs(MCGenInfo.MCCollId); // link to stramccollision table } - } - - histos.fill(HIST("Pi0QA/h3dMassPi0BeforeSel_Candidates"), centrality, pi0Pt, pi0Mass); - - // Photon-specific selections - auto posTrackGamma1 = gamma1.template posTrackExtra_as(); - auto negTrackGamma1 = gamma1.template negTrackExtra_as(); - auto posTrackGamma2 = gamma2.template posTrackExtra_as(); - auto negTrackGamma2 = gamma2.template negTrackExtra_as(); - - // Gamma1 Selection - bool passedTPCGamma1 = (TMath::Abs(posTrackGamma1.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas) || - (TMath::Abs(negTrackGamma1.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas); - - if (TMath::Abs(gamma1.mGamma()) > Pi0PhotonMaxMass || - gamma1.qtarm() >= Pi0PhotonMaxQt || - TMath::Abs(gamma1.alpha()) >= Pi0PhotonMaxAlpha || - TMath::Abs(gamma1.dcapostopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma1.dcanegtopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma1.dcaV0daughters()) > Pi0PhotonMaxDCAV0Dau || - TMath::Abs(gamma1.negativeeta()) >= Pi0PhotonMaxEta || - TMath::Abs(gamma1.positiveeta()) >= Pi0PhotonMaxEta || - gamma1.v0cosPA() <= Pi0PhotonMinV0cospa || - gamma1.v0radius() <= Pi0PhotonMinRadius || - gamma1.v0radius() >= Pi0PhotonMaxRadius || - posTrackGamma1.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - negTrackGamma1.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - !passedTPCGamma1) { - return; - } - // Gamma2 Selection - bool passedTPCGamma2 = (TMath::Abs(posTrackGamma2.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas) || - (TMath::Abs(negTrackGamma2.tpcNSigmaEl()) < Pi0PhotonMaxTPCNSigmas); - - if (TMath::Abs(gamma2.mGamma()) > Pi0PhotonMaxMass || - gamma2.qtarm() >= Pi0PhotonMaxQt || - TMath::Abs(gamma2.alpha()) >= Pi0PhotonMaxAlpha || - TMath::Abs(gamma2.dcapostopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma2.dcanegtopv()) < Pi0PhotonMinDCADauToPv || - TMath::Abs(gamma2.dcaV0daughters()) > Pi0PhotonMaxDCAV0Dau || - TMath::Abs(gamma2.negativeeta()) >= Pi0PhotonMaxEta || - TMath::Abs(gamma2.positiveeta()) >= Pi0PhotonMaxEta || - gamma2.v0cosPA() <= Pi0PhotonMinV0cospa || - gamma2.v0radius() <= Pi0PhotonMinRadius || - gamma2.v0radius() >= Pi0PhotonMaxRadius || - posTrackGamma2.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - negTrackGamma2.tpcCrossedRows() < Pi0PhotonMinTPCCrossedRows || - !passedTPCGamma2) { - return; - } - - // Pi0-specific selections: - if (TMath::Abs(pi0Y) > 0.5) { - return; + // Sigma0/ASigma0 + if (fillSigma0Tables && (MCGenInfo.IsSigma0 || MCGenInfo.IsAntiSigma0)) { + sigma0Gens(MCGenInfo.IsSigma0, MCGenInfo.IsProducedByGenerator, MCGenInfo.MCPt); + sigma0GenCollRefs(MCGenInfo.MCCollId); // link to stramccollision table + } } - - // Fill histograms - histos.fill(HIST("Pi0QA/h3dMassPi0AfterSel_Candidates"), centrality, pi0Pt, pi0Mass); - if (fIsMC && fIsPi0) - histos.fill(HIST("Pi0QA/h3dMassPi0AfterSel_MCAssoc"), centrality, pi0Pt, pi0Mass); } + //_______________________________________________ // Process photon candidate template - bool processPhotonCandidate(TV0Object const& gamma, TCollision collision) + bool processPhotonCandidate(TV0Object const& gamma, TCollision const& collision) { + // V0 type selection if (gamma.v0Type() == 0) return false; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + float PhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); + histos.fill(HIST("PhotonSel/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("PhotonSel/h2dMassGammaVsLambda"), gamma.mGamma(), gamma.mLambda()); + if (useMLScores) { - // Gamma selection: if (gamma.gammaBDTScore() <= Gamma_MLThreshold) return false; @@ -853,7 +701,6 @@ struct sigma0builder { histos.fill(HIST("PhotonSel/hPhotonMass"), gamma.mGamma()); if ((gamma.mGamma() < 0) || (gamma.mGamma() > PhotonMaxMass)) return false; - float PhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); histos.fill(HIST("PhotonSel/hPhotonNegEta"), gamma.negativeeta()); histos.fill(HIST("PhotonSel/hPhotonPosEta"), gamma.positiveeta()); histos.fill(HIST("PhotonSel/hPhotonY"), PhotonY); @@ -875,18 +722,38 @@ struct sigma0builder { return false; histos.fill(HIST("PhotonSel/hSelectionStatistics"), 6.); } - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + histos.fill(HIST("PhotonSel/h2dV0XY"), gamma.x(), gamma.y()); histos.fill(HIST("PhotonSel/h3dPhotonMass"), centrality, gamma.pt(), gamma.mGamma()); + + //_______________________________________________ + // MC Processing + if constexpr (requires { gamma.motherMCPartId(); }) { + if (gamma.has_v0MCCore()) { + auto gammaMC = gamma.template v0MCCore_as>(); + if (gammaMC.pdgCode() == 22) { + histos.fill(HIST("MC/h2dGammaXYConversion"), gamma.x(), gamma.y()); + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocGamma"), centrality, gamma.pt()); + } + } + } + return true; } - // Process photon candidate + //_______________________________________________ + // Process lambda candidate template - bool processLambdaCandidate(TV0Object const& lambda, TCollision collision) + bool processLambdaCandidate(TV0Object const& lambda, TCollision const& collision) { + // V0 type selection if (lambda.v0Type() != 1) return false; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("LambdaSel/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("LambdaSel/h2dMassLambdaVsGamma"), lambda.mLambda(), lambda.mGamma()); + if (useMLScores) { if ((lambda.lambdaBDTScore() <= Lambda_MLThreshold) && (lambda.antiLambdaBDTScore() <= AntiLambda_MLThreshold)) return false; @@ -920,116 +787,152 @@ struct sigma0builder { histos.fill(HIST("LambdaSel/hSelectionStatistics"), 6.); } - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); histos.fill(HIST("LambdaSel/h3dLambdaMass"), centrality, lambda.pt(), lambda.mLambda()); histos.fill(HIST("LambdaSel/h3dALambdaMass"), centrality, lambda.pt(), lambda.mAntiLambda()); + //_______________________________________________ + // MC Processing (if available) + if constexpr (requires { lambda.motherMCPartId(); }) { + if (lambda.has_v0MCCore()) { + auto lambdaMC = lambda.template v0MCCore_as>(); + if (lambdaMC.pdgCode() == 3122) // Is Lambda + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocLambda"), centrality, lambda.pt()); + if (lambdaMC.pdgCode() == -3122) // Is AntiLambda + histos.fill(HIST("MC/h2dPtVsCentrality_MCAssocALambda"), centrality, lambda.pt()); + } + } + return true; } - /////////// - // Process sigma candidate and store properties in object - template - bool buildSigma0(TV0Object const& lambda, TV0Object const& gamma, TCollision collision) + + //_______________________________________________ + // Build pi0 candidate for QA + template + bool buildPi0(TV0Object const& gamma1, TV0Object const& gamma2, TCollision const& collision, TMCParticles const& mcparticles) { + //_______________________________________________ + // Check if both V0s are made of the same tracks + if (gamma1.posTrackExtraId() == gamma2.posTrackExtraId() || + gamma1.negTrackExtraId() == gamma2.negTrackExtraId()) { + return false; + } + + //_______________________________________________ + // Calculate pi0 properties + std::array pVecGamma1{gamma1.px(), gamma1.py(), gamma1.pz()}; + std::array pVecGamma2{gamma2.px(), gamma2.py(), gamma2.pz()}; + std::array arrpi0{pVecGamma1, pVecGamma2}; + float pi0Mass = RecoDecay::m(arrpi0, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassPhoton}); + float pi0Y = RecoDecay::y(std::array{gamma1.px() + gamma2.px(), gamma1.py() + gamma2.py(), gamma1.pz() + gamma2.pz()}, o2::constants::physics::MassPi0); + + //_______________________________________________ + // Pi0-specific selections: + if (TMath::Abs(pi0Y) > Pi0MaxRap) + return false; + + if (TMath::Abs(pi0Mass - o2::constants::physics::MassPi0) > Pi0MassWindow) + return false; + + // Fill optional tables for QA + // Define the table! + auto posTrackGamma1 = gamma1.template posTrackExtra_as(); + auto negTrackGamma1 = gamma1.template negTrackExtra_as(); + auto posTrackGamma2 = gamma2.template posTrackExtra_as(); + auto negTrackGamma2 = gamma2.template negTrackExtra_as(); + + // Calculate Pi0 topological info + auto pi0TopoInfo = propagateV0PairToDCA(gamma1, gamma2); + + // Check if MC data and populate corresponding table + if constexpr (requires { gamma1.motherMCPartId(); gamma2.motherMCPartId(); }) { + auto pi0MCInfo = getV0PairMCInfo(gamma1, gamma2, collision, mcparticles); + + pi0coresmc(pi0MCInfo.V0PairMCRadius, pi0MCInfo.V0PairPDGCode, pi0MCInfo.V0PairPDGCodeMother, pi0MCInfo.V0PairMCProcess, pi0MCInfo.fV0PairProducedByGenerator, + pi0MCInfo.V01MCpx, pi0MCInfo.V01MCpy, pi0MCInfo.V01MCpz, + pi0MCInfo.fIsV01Primary, pi0MCInfo.V01PDGCode, pi0MCInfo.V01PDGCodeMother, pi0MCInfo.fIsV01CorrectlyAssign, + pi0MCInfo.V02MCpx, pi0MCInfo.V02MCpy, pi0MCInfo.V02MCpz, + pi0MCInfo.fIsV02Primary, pi0MCInfo.V02PDGCode, pi0MCInfo.V02PDGCodeMother, pi0MCInfo.fIsV02CorrectlyAssign); + } + + pi0cores(pi0TopoInfo.X, pi0TopoInfo.Y, pi0TopoInfo.Z, pi0TopoInfo.DCADau, pi0TopoInfo.CosPA, + gamma1.px(), gamma1.py(), gamma1.pz(), + gamma1.mGamma(), gamma1.qtarm(), gamma1.alpha(), gamma1.dcapostopv(), gamma1.dcanegtopv(), gamma1.dcaV0daughters(), + gamma1.negativeeta(), gamma1.positiveeta(), gamma1.v0cosPA(), gamma1.v0radius(), gamma1.z(), + posTrackGamma1.tpcCrossedRows(), negTrackGamma1.tpcCrossedRows(), posTrackGamma1.tpcNSigmaEl(), negTrackGamma1.tpcNSigmaEl(), gamma1.v0Type(), + gamma2.px(), gamma2.py(), gamma2.pz(), + gamma2.mGamma(), gamma2.qtarm(), gamma2.alpha(), gamma2.dcapostopv(), gamma2.dcanegtopv(), gamma2.dcaV0daughters(), + gamma2.negativeeta(), gamma2.positiveeta(), gamma2.v0cosPA(), gamma2.v0radius(), gamma2.z(), + posTrackGamma2.tpcCrossedRows(), negTrackGamma2.tpcCrossedRows(), posTrackGamma2.tpcNSigmaEl(), negTrackGamma2.tpcNSigmaEl(), gamma2.v0Type()); + + pi0coresRefs(collision.globalIndex()); + + return true; + } + + //_______________________________________________ + // Build sigma0 candidate + template + bool buildSigma0(TV0Object const& lambda, TV0Object const& gamma, TCollision const& collision, TMCParticles const& mcparticles) + { + //_______________________________________________ // Checking if both V0s are made of the very same tracks if (gamma.posTrackExtraId() == lambda.posTrackExtraId() || gamma.negTrackExtraId() == lambda.negTrackExtraId()) { return false; } - // Sigma0 candidate properties + //_______________________________________________ + // Sigma0 pre-selections std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; float sigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float sigmaY = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + float sigmaY = -999.f; - // Before any selection - histos.fill(HIST("SigmaSel/h3dMassSigma0BeforeSel"), centrality, SigmapT, sigmaMass); + if constexpr (requires { gamma.pxMC(); lambda.pxMC(); }) // If MC + sigmaY = RecoDecay::y(std::array{gamma.pxMC() + lambda.pxMC(), gamma.pyMC() + lambda.pyMC(), gamma.pzMC() + lambda.pzMC()}, o2::constants::physics::MassSigma0); + else // If DATA + sigmaY = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 1.); - histos.fill(HIST("SigmaSel/hSigmaMass"), sigmaMass); - histos.fill(HIST("SigmaSel/hSigmaMassWindow"), sigmaMass - 1.192642); - - if (fillQAhistos) { - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambda"), gamma.mGamma(), gamma.mLambda()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsGamma"), lambda.mLambda(), lambda.mGamma()); - histos.fill(HIST("GeneralQA/h3dMassSigma0VsDaupTs"), gamma.pt(), lambda.pt(), sigmaMass); - } - - if (TMath::Abs(sigmaMass - 1.192642) > Sigma0Window) + if (TMath::Abs(sigmaMass - o2::constants::physics::MassSigma0) > Sigma0Window) return false; - histos.fill(HIST("SigmaSel/hSigmaY"), sigmaY); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 2.); - if (TMath::Abs(sigmaY) > SigmaMaxRap) return false; histos.fill(HIST("SigmaSel/hSigmaMassSelected"), sigmaMass); histos.fill(HIST("SigmaSel/hSelectionStatistics"), 3.); + //_______________________________________________ + // Calculate properties & Fill tables - if (fillQAhistos) { - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0SAfterMassSel"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0SAfterMassSel"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambdaAfterMassSel"), gamma.mGamma(), lambda.mLambda()); - histos.fill(HIST("GeneralQA/h2dV0XY"), gamma.x(), gamma.y()); - } + // Sigma0 topological info + auto sigma0TopoInfo = propagateV0PairToDCA(gamma, lambda); - histos.fill(HIST("SigmaSel/h3dMassSigma0AfterSel"), centrality, SigmapT, sigmaMass); + sigma0cores(sigma0TopoInfo.X, sigma0TopoInfo.Y, sigma0TopoInfo.Z, sigma0TopoInfo.DCADau, + gamma.px(), gamma.py(), gamma.pz(), gamma.mGamma(), lambda.px(), lambda.py(), lambda.pz(), lambda.mLambda(), lambda.mAntiLambda()); - return true; - } + // MC properties + if constexpr (requires { gamma.motherMCPartId(); lambda.motherMCPartId(); }) { + auto sigma0MCInfo = getV0PairMCInfo(gamma, lambda, collision, mcparticles); - // Fill tables with reconstructed sigma0 candidate - template - void fillTables(TV0Object const& lambda, TV0Object const& gamma, TCollision const& coll) - { - float GammaBDTScore = gamma.gammaBDTScore(); - float LambdaBDTScore = lambda.lambdaBDTScore(); - float AntiLambdaBDTScore = lambda.antiLambdaBDTScore(); + sigma0mccores(sigma0MCInfo.V0PairMCRadius, sigma0MCInfo.V0PairPDGCode, sigma0MCInfo.V0PairPDGCodeMother, sigma0MCInfo.V0PairMCProcess, sigma0MCInfo.fV0PairProducedByGenerator, + sigma0MCInfo.V01MCpx, sigma0MCInfo.V01MCpy, sigma0MCInfo.V01MCpz, + sigma0MCInfo.fIsV01Primary, sigma0MCInfo.V01PDGCode, sigma0MCInfo.V01PDGCodeMother, sigma0MCInfo.fIsV01CorrectlyAssign, + sigma0MCInfo.V02MCpx, sigma0MCInfo.V02MCpy, sigma0MCInfo.V02MCpz, + sigma0MCInfo.fIsV02Primary, sigma0MCInfo.V02PDGCode, sigma0MCInfo.V02PDGCodeMother, sigma0MCInfo.fIsV02CorrectlyAssign); + } + + // Sigma0s -> stracollisions link + sigma0CollRefs(collision.globalIndex()); - // Daughters related - /// Photon + //_______________________________________________ + // Photon extra properties auto posTrackGamma = gamma.template posTrackExtra_as(); auto negTrackGamma = gamma.template negTrackExtra_as(); - float fPhotonPt = gamma.pt(); - float fPhotonMass = gamma.mGamma(); - float fPhotonQt = gamma.qtarm(); - float fPhotonAlpha = gamma.alpha(); - float fPhotonRadius = gamma.v0radius(); - float fPhotonCosPA = gamma.v0cosPA(); - float fPhotonDCADau = gamma.dcaV0daughters(); - float fPhotonDCANegPV = gamma.dcanegtopv(); - float fPhotonDCAPosPV = gamma.dcapostopv(); - float fPhotonZconv = gamma.z(); - float fPhotonEta = gamma.eta(); - float fPhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); - float fPhotonPhi = RecoDecay::phi(gamma.px(), gamma.py()); - float fPhotonPosTPCNSigmaEl = posTrackGamma.tpcNSigmaEl(); - float fPhotonNegTPCNSigmaEl = negTrackGamma.tpcNSigmaEl(); - float fPhotonPosTPCNSigmaPi = posTrackGamma.tpcNSigmaPi(); - float fPhotonNegTPCNSigmaPi = negTrackGamma.tpcNSigmaPi(); - uint8_t fPhotonPosTPCCrossedRows = posTrackGamma.tpcCrossedRows(); - uint8_t fPhotonNegTPCCrossedRows = negTrackGamma.tpcCrossedRows(); - float fPhotonPosPt = gamma.positivept(); - float fPhotonNegPt = gamma.negativept(); - float fPhotonPosEta = gamma.positiveeta(); - float fPhotonNegEta = gamma.negativeeta(); - float fPhotonPosY = RecoDecay::y(std::array{gamma.pxpos(), gamma.pypos(), gamma.pzpos()}, o2::constants::physics::MassElectron); - float fPhotonNegY = RecoDecay::y(std::array{gamma.pxneg(), gamma.pyneg(), gamma.pzneg()}, o2::constants::physics::MassElectron); - float fPhotonPsiPair = gamma.psipair(); - int fPhotonPosITSCls = posTrackGamma.itsNCls(); - int fPhotonNegITSCls = negTrackGamma.itsNCls(); - float fPhotonPosITSChi2PerNcl = posTrackGamma.itsChi2PerNcl(); - float fPhotonNegITSChi2PerNcl = negTrackGamma.itsChi2PerNcl(); - uint8_t fPhotonV0Type = gamma.v0Type(); - uint8_t fPhotonPosTrackCode = ((uint8_t(posTrackGamma.hasTPC()) << hasTPC) | (uint8_t(posTrackGamma.hasITSTracker()) << hasITSTracker) | (uint8_t(posTrackGamma.hasITSAfterburner()) << hasITSAfterburner) | @@ -1042,50 +945,16 @@ struct sigma0builder { (uint8_t(negTrackGamma.hasTRD()) << hasTRD) | (uint8_t(negTrackGamma.hasTOF()) << hasTOF)); - // Lambda + sigmaPhotonExtras(gamma.qtarm(), gamma.alpha(), gamma.v0cosPA(), gamma.dcaV0daughters(), gamma.dcanegtopv(), gamma.dcapostopv(), gamma.v0radius(), gamma.z(), + posTrackGamma.tpcNSigmaEl(), negTrackGamma.tpcNSigmaEl(), posTrackGamma.tpcCrossedRows(), negTrackGamma.tpcCrossedRows(), + gamma.positiveeta(), gamma.negativeeta(), gamma.psipair(), posTrackGamma.itsNCls(), negTrackGamma.itsNCls(), posTrackGamma.itsChi2PerNcl(), negTrackGamma.itsChi2PerNcl(), + fPhotonPosTrackCode, fPhotonNegTrackCode, gamma.v0Type()); + + //_______________________________________________ + // Lambda extra properties auto posTrackLambda = lambda.template posTrackExtra_as(); auto negTrackLambda = lambda.template negTrackExtra_as(); - float fLambdaPt = lambda.pt(); - float fLambdaMass = lambda.mLambda(); - float fAntiLambdaMass = lambda.mAntiLambda(); - float fLambdaQt = lambda.qtarm(); - float fLambdaAlpha = lambda.alpha(); - float fLambdaLifeTime = lambda.distovertotmom(coll.posX(), coll.posY(), coll.posZ()) * o2::constants::physics::MassLambda0; - float fLambdaRadius = lambda.v0radius(); - float fLambdaCosPA = lambda.v0cosPA(); - float fLambdaDCADau = lambda.dcaV0daughters(); - float fLambdaDCANegPV = lambda.dcanegtopv(); - float fLambdaDCAPosPV = lambda.dcapostopv(); - float fLambdaEta = lambda.eta(); - float fLambdaY = lambda.yLambda(); - float fLambdaPhi = RecoDecay::phi(lambda.px(), lambda.py()); - float fLambdaPosPrTPCNSigma = posTrackLambda.tpcNSigmaPr(); - float fLambdaPosPiTPCNSigma = posTrackLambda.tpcNSigmaPi(); - float fLambdaNegPrTPCNSigma = negTrackLambda.tpcNSigmaPr(); - float fLambdaNegPiTPCNSigma = negTrackLambda.tpcNSigmaPi(); - - float fLambdaPrTOFNSigma = lambda.tofNSigmaLaPr(); - float fLambdaPiTOFNSigma = lambda.tofNSigmaLaPi(); - float fALambdaPrTOFNSigma = lambda.tofNSigmaALaPr(); - float fALambdaPiTOFNSigma = lambda.tofNSigmaALaPi(); - - uint8_t fLambdaPosTPCCrossedRows = posTrackLambda.tpcCrossedRows(); - uint8_t fLambdaNegTPCCrossedRows = negTrackLambda.tpcCrossedRows(); - float fLambdaPosPt = lambda.positivept(); - float fLambdaNegPt = lambda.negativept(); - float fLambdaPosEta = lambda.positiveeta(); - float fLambdaNegEta = lambda.negativeeta(); - float fLambdaPosPrY = RecoDecay::y(std::array{lambda.pxpos(), lambda.pypos(), lambda.pzpos()}, o2::constants::physics::MassProton); - float fLambdaPosPiY = RecoDecay::y(std::array{lambda.pxpos(), lambda.pypos(), lambda.pzpos()}, o2::constants::physics::MassPionCharged); - float fLambdaNegPrY = RecoDecay::y(std::array{lambda.pxneg(), lambda.pyneg(), lambda.pzneg()}, o2::constants::physics::MassProton); - float fLambdaNegPiY = RecoDecay::y(std::array{lambda.pxneg(), lambda.pyneg(), lambda.pzneg()}, o2::constants::physics::MassPionCharged); - int fLambdaPosITSCls = posTrackLambda.itsNCls(); - int fLambdaNegITSCls = negTrackLambda.itsNCls(); - float fLambdaPosITSChi2PerNcl = posTrackLambda.itsChi2PerNcl(); - float fLambdaNegITSChi2PerNcl = negTrackLambda.itsChi2PerNcl(); - uint8_t fLambdaV0Type = lambda.v0Type(); - uint8_t fLambdaPosTrackCode = ((uint8_t(posTrackLambda.hasTPC()) << hasTPC) | (uint8_t(posTrackLambda.hasITSTracker()) << hasITSTracker) | (uint8_t(posTrackLambda.hasITSAfterburner()) << hasITSAfterburner) | @@ -1098,109 +967,62 @@ struct sigma0builder { (uint8_t(negTrackLambda.hasTRD()) << hasTRD) | (uint8_t(negTrackLambda.hasTOF()) << hasTOF)); - // Sigma0 candidate properties - std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; - std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; - auto arrMom = std::array{pVecPhotons, pVecLambda}; - TVector3 v1(gamma.px(), gamma.py(), gamma.pz()); - TVector3 v2(lambda.px(), lambda.py(), lambda.pz()); - - // Sigma related - float fSigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float fSigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float fSigmaRap = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - float fSigmaOPAngle = v1.Angle(v2); - float fSigmaCentrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - uint64_t fSigmaTimeStamp = coll.timestamp(); - int fSigmaRunNumber = coll.runNumber(); - - // Filling TTree for ML analysis - sigma0cores(fSigmapT, fSigmaMass, fSigmaRap, fSigmaOPAngle, fSigmaCentrality, fSigmaRunNumber, fSigmaTimeStamp); - - sigmaPhotonExtras(fPhotonPt, fPhotonMass, fPhotonQt, fPhotonAlpha, fPhotonRadius, - fPhotonCosPA, fPhotonDCADau, fPhotonDCANegPV, fPhotonDCAPosPV, fPhotonZconv, - fPhotonEta, fPhotonY, fPhotonPhi, fPhotonPosTPCNSigmaEl, fPhotonNegTPCNSigmaEl, fPhotonPosTPCNSigmaPi, fPhotonNegTPCNSigmaPi, fPhotonPosTPCCrossedRows, - fPhotonNegTPCCrossedRows, fPhotonPosPt, fPhotonNegPt, fPhotonPosEta, - fPhotonNegEta, fPhotonPosY, fPhotonNegY, fPhotonPsiPair, - fPhotonPosITSCls, fPhotonNegITSCls, fPhotonPosITSChi2PerNcl, fPhotonNegITSChi2PerNcl, fPhotonPosTrackCode, fPhotonNegTrackCode, - fPhotonV0Type, GammaBDTScore); - - sigmaLambdaExtras(fLambdaPt, fLambdaMass, fAntiLambdaMass, fLambdaQt, fLambdaAlpha, fLambdaLifeTime, - fLambdaRadius, fLambdaCosPA, fLambdaDCADau, fLambdaDCANegPV, - fLambdaDCAPosPV, fLambdaEta, fLambdaY, fLambdaPhi, fLambdaPosPrTPCNSigma, - fLambdaPosPiTPCNSigma, fLambdaNegPrTPCNSigma, fLambdaNegPiTPCNSigma, + float fLambdaLifeTime = lambda.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + float fLambdaPrTOFNSigma = -999.f; + float fLambdaPiTOFNSigma = -999.f; + float fALambdaPrTOFNSigma = -999.f; + float fALambdaPiTOFNSigma = -999.f; + + if constexpr (requires { lambda.tofNSigmaLaPr(); }) { // If TOF info avaiable + fLambdaPrTOFNSigma = lambda.tofNSigmaLaPr(); + fLambdaPiTOFNSigma = lambda.tofNSigmaLaPi(); + fALambdaPrTOFNSigma = lambda.tofNSigmaALaPr(); + fALambdaPiTOFNSigma = lambda.tofNSigmaALaPi(); + } + + sigmaLambdaExtras(lambda.qtarm(), lambda.alpha(), fLambdaLifeTime, lambda.v0radius(), lambda.v0cosPA(), lambda.dcaV0daughters(), lambda.dcanegtopv(), lambda.dcapostopv(), + posTrackLambda.tpcNSigmaPr(), posTrackLambda.tpcNSigmaPi(), negTrackLambda.tpcNSigmaPr(), negTrackLambda.tpcNSigmaPi(), fLambdaPrTOFNSigma, fLambdaPiTOFNSigma, fALambdaPrTOFNSigma, fALambdaPiTOFNSigma, - fLambdaPosTPCCrossedRows, fLambdaNegTPCCrossedRows, fLambdaPosPt, fLambdaNegPt, fLambdaPosEta, - fLambdaNegEta, fLambdaPosPrY, fLambdaPosPiY, fLambdaNegPrY, fLambdaNegPiY, - fLambdaPosITSCls, fLambdaNegITSCls, fLambdaPosITSChi2PerNcl, fLambdaNegITSChi2PerNcl, fLambdaPosTrackCode, fLambdaNegTrackCode, - fLambdaV0Type, LambdaBDTScore, AntiLambdaBDTScore); + posTrackLambda.tpcCrossedRows(), negTrackLambda.tpcCrossedRows(), + lambda.positiveeta(), lambda.negativeeta(), + posTrackLambda.itsNCls(), negTrackLambda.itsNCls(), posTrackLambda.itsChi2PerNcl(), negTrackLambda.itsChi2PerNcl(), + fLambdaPosTrackCode, fLambdaNegTrackCode, lambda.v0Type()); + + return true; } - void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + // Process photon and lambda candidates to build sigma0 candidates + template + void dataProcess(TCollision const& collisions, TV0s const& fullV0s, TMCParticles const& mcparticles) { - // Initialize auxiliary vectors + //_______________________________________________ + // Initial setup + // Auxiliary vectors to store best candidates std::vector bestGammasArray; std::vector bestLambdasArray; - // brute force grouped index construction + // Custom grouping std::vector> v0grouped(collisions.size()); for (const auto& v0 : fullV0s) { v0grouped[v0.straCollisionId()].push_back(v0.globalIndex()); } + //_______________________________________________ + // Collisions loop for (const auto& coll : collisions) { // Clear vectors bestGammasArray.clear(); bestLambdasArray.clear(); - if (!IsEventAccepted(coll, true)) - continue; - float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - - bool fhasMCColl = false; - if (coll.has_straMCCollision()) - fhasMCColl = true; - - //_______________________________________________ - // Retrieving IR info - float interactionRate = -1; - if (fGetIR) { - interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; - if (interactionRate < 0) - histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); - - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); - } + histos.fill(HIST("hEventCentrality"), centrality); //_______________________________________________ // V0s loop for (size_t i = 0; i < v0grouped[coll.globalIndex()].size(); i++) { auto v0 = fullV0s.rawIteratorAt(v0grouped[coll.globalIndex()][i]); - if (!v0.has_v0MCCore()) - continue; - - auto v0MC = v0.v0MCCore_as>(); - - if (v0MC.pdgCode() == 22) { - histos.fill(HIST("MC/h2dGammaXYConversion"), v0.x(), v0.y()); - float GammaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma)); - if (GammaY < 0.5) { // rapidity selection - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma"), centrality, v0.pt()); // isgamma - } - } - - float lambdaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassLambda)); - if (lambdaY < 0.5) { - if (v0MC.pdgCode() == 3122) // Is Lambda - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda"), centrality, v0.pt()); - if (v0MC.pdgCode() == -3122) // Is AntiLambda - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda"), centrality, v0.pt()); - } - if (processPhotonCandidate(v0, coll)) // selecting photons bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates @@ -1209,117 +1031,41 @@ struct sigma0builder { } //_______________________________________________ - // Pi0 optional loop - if (doPi0QA) { - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { - auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - runPi0QA(gamma1, gamma2, coll); - } + // Wrongly collision association study (MC-specific) + if constexpr (requires { coll.StraMCCollisionId(); }) { + if (doAssocStudy) { + analyzeV0CollAssoc(coll, fullV0s, bestGammasArray, true); // Photon-analysis + analyzeV0CollAssoc(coll, fullV0s, bestLambdasArray, false); // Lambda-analysis } } //_______________________________________________ - // Wrongly collision association study - if (doAssocStudy && fhasMCColl) { - analyzeV0CollAssoc(coll, fullV0s, bestGammasArray, interactionRate, true); // Gamma - analyzeV0CollAssoc(coll, fullV0s, bestLambdasArray, interactionRate, false); // Lambda - } - - //_______________________________________________ - // Sigma0 loop + // V0 nested loop for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); - - if (!gamma.has_v0MCCore()) - continue; + auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - auto gammaMC = gamma.v0MCCore_as>(); + //_______________________________________________ + // Sigma0 loop + if (fillSigma0Tables) { + for (size_t j = 0; j < bestLambdasArray.size(); ++j) { + auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); - bool fIsPhotonCorrectlyAssign = false; - if (fhasMCColl) { - auto gammaMCCollision = coll.template straMCCollision_as>(); - fIsPhotonCorrectlyAssign = (gammaMC.straMCCollisionId() == gammaMCCollision.globalIndex()); - } - - for (size_t j = 0; j < bestLambdasArray.size(); ++j) { - auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); - - if (!lambda.has_v0MCCore()) - continue; - - auto lambdaMC = lambda.v0MCCore_as>(); - - // Sigma0 candidate properties - std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; - std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; - auto arrMom = std::array{pVecPhotons, pVecLambda}; - float SigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); - - // MC properties - bool fIsSigma = false; - bool fIsAntiSigma = false; - bool fIsPhotonPrimary = gammaMC.isPhysicalPrimary(); - bool fIsLambdaPrimary = lambdaMC.isPhysicalPrimary(); - bool fIsLambdaCorrectlyAssign = false; - - int PhotonCandPDGCode = gammaMC.pdgCode(); - int PhotonCandPDGCodeMother = gammaMC.pdgCodeMother(); - int LambdaCandPDGCode = lambdaMC.pdgCode(); - int LambdaCandPDGCodeMother = lambdaMC.pdgCodeMother(); - - float SigmaMCpT = RecoDecay::pt(array{gammaMC.pxMC() + lambdaMC.pxMC(), gammaMC.pyMC() + lambdaMC.pyMC()}); - float PhotonMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); - float LambdaMCpT = RecoDecay::pt(array{lambdaMC.pxMC(), lambdaMC.pyMC()}); - - if (fhasMCColl) { - auto lambdaMCCollision = coll.template straMCCollision_as>(); - fIsLambdaCorrectlyAssign = (lambdaMC.straMCCollisionId() == lambdaMCCollision.globalIndex()); - } - - if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == 3212) && (LambdaCandPDGCode == 3122) && (LambdaCandPDGCodeMother == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) - fIsSigma = true; - if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == -3212) && (LambdaCandPDGCode == -3122) && (LambdaCandPDGCodeMother == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) - fIsAntiSigma = true; - - if (SigmaY < 0.5) { - if (fIsSigma) { - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0"), centrality, SigmaMCpT); - histos.fill(HIST("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc"), SigmaMCpT, LambdaMCpT); - histos.fill(HIST("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc"), SigmaMCpT, PhotonMCpT); - } - if (fIsAntiSigma) - histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0"), centrality, SigmaMCpT); + // Building sigma0 candidate & filling tables + if (!buildSigma0(lambda, gamma1, coll, mcparticles)) + continue; } + } - // Build sigma0 candidate, please - if (!buildSigma0(lambda, gamma, coll)) - continue; + //_______________________________________________ + // pi0 loop + if (fillPi0Tables) { + for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { + auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - if (SigmaY < 0.5) { - if (fIsSigma) - histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0"), centrality, SigmaMCpT); - if (fIsAntiSigma) - histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0"), centrality, SigmaMCpT); + // Building pi0 candidate & filling tables + if (!buildPi0(gamma1, gamma2, coll, mcparticles)) + continue; } - - if (fillBkgQAhistos) - runBkgAnalysis(fIsSigma, fIsAntiSigma, PhotonCandPDGCode, PhotonCandPDGCodeMother, LambdaCandPDGCode, LambdaCandPDGCodeMother, SigmapT, SigmaMass); - - // Fill Tables please - sigma0mccores(fIsSigma, fIsAntiSigma, SigmaMCpT, - PhotonCandPDGCode, PhotonCandPDGCodeMother, fIsPhotonPrimary, PhotonMCpT, fIsPhotonCorrectlyAssign, - LambdaCandPDGCode, LambdaCandPDGCodeMother, fIsLambdaPrimary, LambdaMCpT, fIsLambdaCorrectlyAssign); - - // Filling tables with accepted candidates - fillTables(lambda, gamma, coll); - - nSigmaCandidates++; - if (nSigmaCandidates % 10000 == 0) - LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; } } } @@ -1327,94 +1073,35 @@ struct sigma0builder { void processRealData(soa::Join const& collisions, V0StandardDerivedDatas const& fullV0s, dauTracks const&) { - // Initialize auxiliary vectors - std::vector bestGammasArray; - std::vector bestLambdasArray; - - // brute force grouped index construction - std::vector> v0grouped(collisions.size()); - - for (const auto& v0 : fullV0s) { - v0grouped[v0.straCollisionId()].push_back(v0.globalIndex()); - } - - for (const auto& coll : collisions) { - // Clear vectors - bestGammasArray.clear(); - bestLambdasArray.clear(); - - if (!IsEventAccepted(coll, true)) - continue; - - float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); - - //_______________________________________________ - // Retrieving IR info - float interactionRate = -1; - if (fGetIR) { - interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; - if (interactionRate < 0) - histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); - - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); - } - - //_______________________________________________ - // V0s loop - for (size_t i = 0; i < v0grouped[coll.globalIndex()].size(); i++) { - auto v0 = fullV0s.rawIteratorAt(v0grouped[coll.globalIndex()][i]); - if (processPhotonCandidate(v0, coll)) // selecting photons - bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates - - if (processLambdaCandidate(v0, coll)) // selecting lambdas - bestLambdasArray.push_back(v0.globalIndex()); // Save indices of best lambda candidates - } - - //_______________________________________________ - // Pi0 optional loop - if (doPi0QA) { - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); - for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { - auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); - runPi0QA(gamma1, gamma2, coll); - } - } - } - - //_______________________________________________ - // Sigma0 nested loop - for (size_t i = 0; i < bestGammasArray.size(); ++i) { - auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); - - for (size_t j = 0; j < bestLambdasArray.size(); ++j) { - auto lambda = fullV0s.rawIteratorAt(bestLambdasArray[j]); + dataProcess(collisions, fullV0s, nullptr); + } - // Building sigma0 candidate - if (!buildSigma0(lambda, gamma, coll)) - continue; + void processRealDataWithTOF(soa::Join const& collisions, V0TOFStandardDerivedDatas const& fullV0s, dauTracks const&) + { + dataProcess(collisions, fullV0s, nullptr); + } - // Filling tables with accepted candidates - fillTables(lambda, gamma, coll); + void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& fullV0s, aod::McParticles const& mcParticles, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + { + dataProcess(collisions, fullV0s, mcParticles); + } - nSigmaCandidates++; - if (nSigmaCandidates % 10000 == 0) - LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; - } - } - } + void processMonteCarloWithTOF(soa::Join const& collisions, V0TOFDerivedMCDatas const& fullV0s, aod::McParticles const& mcParticles, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + { + dataProcess(collisions, fullV0s, mcParticles); } - // Simulated processing in Run 3 (subscribes to MC information too) - void processGeneratedRun3(soa::Join const& mcCollisions, soa::Join const& V0MCCores, soa::Join const& collisions) + // Simulated processing in Run 3 - run this over original AO2Ds + void processGeneratedRun3(aod::McParticles const& mcParticles) { - analyzeGeneratedV0s(mcCollisions, V0MCCores, collisions); + genProcess(mcParticles); } - PROCESS_SWITCH(sigma0builder, processMonteCarlo, "process as if MC data", false); PROCESS_SWITCH(sigma0builder, processRealData, "process as if real data", true); - PROCESS_SWITCH(sigma0builder, processGeneratedRun3, "process generated MC collisions", false); + PROCESS_SWITCH(sigma0builder, processRealDataWithTOF, "process as if real data", false); + PROCESS_SWITCH(sigma0builder, processMonteCarlo, "process as if MC data", false); + PROCESS_SWITCH(sigma0builder, processMonteCarloWithTOF, "process as if MC data, uses TOF PID info", false); + PROCESS_SWITCH(sigma0builder, processGeneratedRun3, "process generated MC info", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx index d7012626b4f..b4b2d393ec2 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx @@ -644,6 +644,7 @@ struct StrangenessBuilder { histos.add("DeduplicationQA/hBestPA", "hBestPA", kTH1F, {{200, 0.0f, 0.4f}}); histos.add("DeduplicationQA/hBestDCADau", "hBestDCADau", kTH1F, {{200, -10.0f, 10.0f}}); histos.add("DeduplicationQA/hBestMLScore", "hBestMLScore", kTH1F, {{200, 0.0f, 1.0f}}); + histos.add("DeduplicationQA/hPAOfBestMLScore", "hPAOfBestMLScore", kTH1F, {{200, 0.0f, 0.4f}}); } auto hPrimaryV0s = histos.add("hPrimaryV0s", "hPrimaryV0s", kTH1D, {{2, -0.5f, 1.5f}}); @@ -1001,8 +1002,10 @@ struct StrangenessBuilder { V0DuplicateExtras[bestPointingAngleIndex].isBestPA = true; if (bestDCADaughtersIndex != static_cast(-1)) V0DuplicateExtras[bestDCADaughtersIndex].isBestDCADau = true; - if (bestMLScoreIndex != static_cast(-1)) + if (bestMLScoreIndex != static_cast(-1)) { V0DuplicateExtras[bestMLScoreIndex].isBestMLScore = true; + histos.fill(HIST("DeduplicationQA/hPAOfBestMLScore"), V0DuplicateExtras[bestMLScoreIndex].PA); + } // return vector with duplicates info return V0DuplicateExtras; diff --git a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx index c01a0a71cae..6f94ba4dd67 100644 --- a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx @@ -19,45 +19,50 @@ // gianni.shigeru.setoue.liveraro@cern.ch // -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" +#include "PWGLF/DataModel/LFSigmaTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFStrangenessMLTables.h" -#include "PWGLF/DataModel/LFSigmaTables.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include #include #include -#include #include #include -#include +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -using V0MCSigmas = soa::Join; -using V0Sigmas = soa::Join; +using MCSigma0s = soa::Join; +using Sigma0s = soa::Join; -static const std::vector PhotonSels = {"NoSel", "V0Type", "DaupT", "DCADauToPV", +static const std::vector PhotonSels = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; @@ -69,77 +74,139 @@ static const std::vector LambdaSels = {"NoSel", "V0Radius", "DCADau static const std::vector DirList = {"BeforeSel", "AfterSel"}; struct sigmaanalysis { + Service ccdb; + ctpRateFetcher rateFetcher; + + //__________________________________________________ + // For manual sliceBy + // SliceCache cache; + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; + // Event level + Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; + Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + + struct : ConfigurableGroup { + Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; + Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; + Configurable requireNoCollInTimeRangeVzDep{"requireNoCollInTimeRangeVzDep", false, "reject collisions corrupted by the cannibalism, with other collisions with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ"}; + Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; + Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; + Configurable requireINEL0{"requireINEL0", false, "require INEL>0 event selection"}; + Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; + Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; + Configurable useEvtSelInDenomEff{"useEvtSelInDenomEff", false, "Consider event selections in the recoed <-> gen collision association for the denominator (or numerator) of the acc. x eff. (or signal loss)?"}; + Configurable applyZVtxSelOnMCPV{"applyZVtxSelOnMCPV", false, "Apply Z-vtx cut on the PV of the generated collision?"}; + Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; + // fast check on occupancy + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + + // fast check on interaction rate + Configurable minIR{"minIR", -1, "minimum IR collisions"}; + Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; + + } eventSelections; + + // Generated Sigma0s + Configurable mc_keepOnlyFromGenerator{"mc_keepOnlyFromGenerator", true, "if true, consider only particles from generator to calculate efficiency."}; + + // QA Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study. Only works with MC."}; - Configurable fillpTResoQAhistos{"fillpTResoQAhistos", false, "if true, fill MC QA histograms for pT resolution study. Only works with MC."}; + Configurable fillResoQAhistos{"fillResoQAhistos", false, "if true, fill MC QA histograms for pT resolution study. Only works with MC."}; // Analysis strategy: - Configurable fUseMLSel{"fUseMLSel", false, "Flag to use ML selection. If False, the standard selection is applied."}; - Configurable fselLambdaTPCPID{"fselLambdaTPCPID", true, "Flag to select lambda-like candidates using TPC NSigma."}; - Configurable fselLambdaTOFPID{"fselLambdaTOFPID", false, "Flag to select lambda-like candidates using TOF NSigma."}; Configurable doMCAssociation{"doMCAssociation", false, "Flag to process only signal candidates. Use only with processMonteCarlo!"}; + Configurable selRecoFromGenerator{"selRecoFromGenerator", false, "Flag to process only signal candidates from generator"}; Configurable doPhotonLambdaSelQA{"doPhotonLambdaSelQA", false, "Flag to fill photon and lambda QA histos!"}; - // For ML Selection - Configurable Gamma_MLThreshold{"Gamma_MLThreshold", 0.1, "Decision Threshold value to select gammas"}; - Configurable Lambda_MLThreshold{"Lambda_MLThreshold", 0.1, "Decision Threshold value to select lambdas"}; - Configurable AntiLambda_MLThreshold{"AntiLambda_MLThreshold", 0.1, "Decision Threshold value to select antilambdas"}; - - // For Standard Selection: - //// Lambda standard criteria:: - Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; - Configurable LambdaMinDCAPosToPv{"LambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; - Configurable ALambdaMinDCANegToPv{"ALambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; - Configurable ALambdaMinDCAPosToPv{"ALambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; - Configurable LambdaMaxDCAV0Dau{"LambdaMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; - Configurable LambdaMinv0radius{"LambdaMinv0radius", 0.0, "Min V0 radius (cm)"}; - Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 40, "Max V0 radius (cm)"}; - Configurable LambdaMinQt{"LambdaMinQt", 0.01, "Min lambda qt value (AP plot) (GeV/c)"}; - Configurable LambdaMaxQt{"LambdaMaxQt", 0.17, "Max lambda qt value (AP plot) (GeV/c)"}; - Configurable LambdaMinAlpha{"LambdaMinAlpha", 0.25, "Min lambda alpha absolute value (AP plot)"}; - Configurable LambdaMaxAlpha{"LambdaMaxAlpha", 1.0, "Max lambda alpha absolute value (AP plot)"}; - Configurable LambdaMinv0cospa{"LambdaMinv0cospa", 0.95, "Min V0 CosPA"}; - Configurable LambdaMaxLifeTime{"LambdaMaxLifeTime", 30, "Max lifetime"}; - Configurable LambdaWindow{"LambdaWindow", 0.015, "Mass window around expected (in GeV/c2)"}; - Configurable LambdaMaxRap{"LambdaMaxRap", 0.8, "Max lambda rapidity"}; - Configurable LambdaMaxDauEta{"LambdaMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; - Configurable LambdaMaxTPCNSigmas{"LambdaMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; - Configurable LambdaPrMaxTOFNSigmas{"LambdaPrMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable LambdaPiMaxTOFNSigmas{"LambdaPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable LambdaMinTPCCrossedRows{"LambdaMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; - Configurable LambdaMinITSclusters{"LambdaMinITSclusters", 1, "minimum ITS clusters"}; - Configurable LambdaRejectPosITSafterburner{"LambdaRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; - Configurable LambdaRejectNegITSafterburner{"LambdaRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; - - //// Photon standard criteria: - Configurable Photonv0TypeSel{"Photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; - Configurable PhotonDauMinPt{"PhotonDauMinPt", 0.0, "Min daughter pT (GeV/c)"}; - Configurable PhotonMinDCADauToPv{"PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; - Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; - Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; - Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; - Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; - Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; - Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; - Configurable PhotonMinRadius{"PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; - Configurable PhotonMaxRadius{"PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; - Configurable PhotonMaxZ{"PhotonMaxZ", 240, "Max photon conversion point z value (cm)"}; - Configurable PhotonMaxQt{"PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; - Configurable PhotonMaxAlpha{"PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; - Configurable PhotonMinV0cospa{"PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; - Configurable PhotonMaxMass{"PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; - Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; - Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; - Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; - Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; - - Configurable SigmaMaxRap{"SigmaMaxRap", 0.5, "Max sigma0 rapidity"}; + // For Selection: + //// Lambda criteria:: + struct : ConfigurableGroup { + Configurable Lambda_MLThreshold{"Lambda_MLThreshold", 0.1, "Decision Threshold value to select lambdas"}; + Configurable AntiLambda_MLThreshold{"AntiLambda_MLThreshold", 0.1, "Decision Threshold value to select antilambdas"}; + Configurable LambdaMinDCANegToPv{"LambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable LambdaMinDCAPosToPv{"LambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable ALambdaMinDCANegToPv{"ALambdaMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable ALambdaMinDCAPosToPv{"ALambdaMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable LambdaMaxDCAV0Dau{"LambdaMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; + Configurable LambdaMinv0radius{"LambdaMinv0radius", 0.0, "Min V0 radius (cm)"}; + Configurable LambdaMaxv0radius{"LambdaMaxv0radius", 40, "Max V0 radius (cm)"}; + Configurable LambdaMinQt{"LambdaMinQt", 0.01, "Min lambda qt value (AP plot) (GeV/c)"}; + Configurable LambdaMaxQt{"LambdaMaxQt", 0.17, "Max lambda qt value (AP plot) (GeV/c)"}; + Configurable LambdaMinAlpha{"LambdaMinAlpha", 0.25, "Min lambda alpha absolute value (AP plot)"}; + Configurable LambdaMaxAlpha{"LambdaMaxAlpha", 1.0, "Max lambda alpha absolute value (AP plot)"}; + Configurable LambdaMinv0cospa{"LambdaMinv0cospa", 0.95, "Min V0 CosPA"}; + Configurable LambdaMaxLifeTime{"LambdaMaxLifeTime", 30, "Max lifetime"}; + Configurable LambdaWindow{"LambdaWindow", 0.015, "Mass window around expected (in GeV/c2)"}; + Configurable LambdaMaxRap{"LambdaMaxRap", 0.8, "Max lambda rapidity"}; + Configurable LambdaMaxDauEta{"LambdaMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable fselLambdaTPCPID{"fselLambdaTPCPID", true, "Flag to select lambda-like candidates using TPC NSigma."}; + Configurable fselLambdaTOFPID{"fselLambdaTOFPID", false, "Flag to select lambda-like candidates using TOF NSigma."}; + Configurable LambdaMaxTPCNSigmas{"LambdaMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; + Configurable LambdaPrMaxTOFNSigmas{"LambdaPrMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable LambdaPiMaxTOFNSigmas{"LambdaPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable LambdaMinTPCCrossedRows{"LambdaMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; + Configurable LambdaMinITSclusters{"LambdaMinITSclusters", 1, "minimum ITS clusters"}; + Configurable LambdaRejectPosITSafterburner{"LambdaRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; + Configurable LambdaRejectNegITSafterburner{"LambdaRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; + + } lambdaSelections; + + //// Photon criteria: + struct : ConfigurableGroup { + Configurable Gamma_MLThreshold{"Gamma_MLThreshold", 0.1, "Decision Threshold value to select gammas"}; + Configurable Photonv0TypeSel{"Photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable PhotonMinDCADauToPv{"PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; + Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; + Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; + Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; + Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; + Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; + Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; + Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; + Configurable PhotonMinRadius{"PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; + Configurable PhotonMaxRadius{"PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; + Configurable PhotonMaxZ{"PhotonMaxZ", 240, "Max photon conversion point z value (cm)"}; + Configurable PhotonMaxQt{"PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; + Configurable PhotonMaxAlpha{"PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; + Configurable PhotonMinV0cospa{"PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; + Configurable PhotonMaxMass{"PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; + Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; + Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; + } photonSelections; + + struct : ConfigurableGroup { + Configurable Sigma0MaxRap{"Sigma0MaxRap", 0.5, "Max sigma0 rapidity"}; + Configurable Sigma0MaxRadius{"Sigma0MaxRadius", 200, "Max sigma0 decay radius"}; + Configurable Sigma0MaxDCADau{"Sigma0MaxDCADau", 50, "Max sigma0 DCA between daughters"}; + Configurable Sigma0MaxOPAngle{"Sigma0MaxOPAngle", 7, "Max sigma0 OP Angle between daughters"}; + } sigma0Selections; + + struct : ConfigurableGroup { + Configurable Pi0MaxRap{"Pi0MaxRap", 0.5, "Max sigma0 rapidity"}; + Configurable Pi0MaxRadius{"Pi0MaxRadius", 200, "Max sigma0 decay radius"}; + Configurable Pi0MaxDCADau{"Pi0MaxDCADau", 50, "Max sigma0 DCA between daughters"}; + } pi0Selections; // Axis // base properties @@ -149,11 +216,14 @@ struct sigmaanalysis { ConfigurableAxis axisDeltaPt{"axisDeltaPt", {400, -50.0, 50.0}, ""}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; + ConfigurableAxis axisGeneratorIds{"axisGeneratorIds", {256, -0.5f, 255.5f}, "axis for generatorIds"}; // Invariant Mass ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; + ConfigurableAxis axisPi0Mass{"axisPi0Mass", {200, 0.08f, 0.18f}, "M_{#Pi^{0}}"}; // AP plot axes ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; @@ -168,7 +238,8 @@ struct sigmaanalysis { ConfigurableAxis axisLifetime{"axisLifetime", {100, 0, 100}, "Chi2 Per Ncl"}; // topological variable QA axes - ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisV0PairRadius{"axisV0PairRadius", {200, 0.0f, 20.0f}, "V0Pair radius (cm)"}; ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; @@ -184,173 +255,586 @@ struct sigmaanalysis { void init(InitContext const&) { + LOGF(info, "Initializing now: cross-checking correctness..."); + if ((doprocessRealData + doprocessMonteCarlo + doprocessPi0RealData + doprocessPi0MonteCarlo > 1) || + (doprocessGeneratedRun3 + doprocessPi0GeneratedRun3 > 1)) { + LOGF(fatal, "You have enabled more than one process function. Please check your configuration! Aborting now."); + } - for (const auto& histodir : DirList) { - - histos.add(histodir + "/Photon/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); - histos.add(histodir + "/Photon/hV0Type", "hV0Type", kTH1F, {{8, 0.5f, 8.5f}}); - histos.add(histodir + "/Photon/hNegpT", "hNegpT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hPospT", "hPospT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hDCANegToPV", "hDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Photon/hDCAPosToPV", "hDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Photon/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); - histos.add(histodir + "/Photon/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Photon/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/Photon/hpT", "hpT", kTH1F, {axisPt}); - histos.add(histodir + "/Photon/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hPosEta", "hPosEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hNegEta", "hNegEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Photon/hRadius", "hRadius", kTH1F, {axisRadius}); - histos.add(histodir + "/Photon/hZ", "hZ", kTH1F, {axisZ}); - histos.add(histodir + "/Photon/h2dRZCut", "h2dRZCut", kTH2F, {axisZ, axisRadius}); - histos.add(histodir + "/Photon/h2dRZPlane", "h2dRZPlane", kTH2F, {axisZ, axisRadius}); - histos.add(histodir + "/Photon/hCosPA", "hCosPA", kTH1F, {axisCosPA}); - histos.add(histodir + "/Photon/hPsiPair", "hPsiPair", kTH1F, {axisPsiPair}); - histos.add(histodir + "/Photon/hPhi", "hPhi", kTH1F, {axisPhi}); - histos.add(histodir + "/Photon/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisPhotonMass}); - histos.add(histodir + "/Photon/hMass", "hMass", kTH1F, {axisPhotonMass}); - - histos.add(histodir + "/Lambda/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); - histos.add(histodir + "/Lambda/hRadius", "hRadius", kTH1F, {axisRadius}); - histos.add(histodir + "/Lambda/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); - histos.add(histodir + "/Lambda/hCosPA", "hCosPA", kTH1F, {axisCosPA}); - histos.add(histodir + "/Lambda/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hPosEta", "hPosEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hNegEta", "hNegEta", kTH1F, {axisRapidity}); - histos.add(histodir + "/Lambda/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Lambda/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); - histos.add(histodir + "/Lambda/hPosITSCls", "hPosITSCls", kTH1F, {axisNCls}); - histos.add(histodir + "/Lambda/hNegITSCls", "hNegITSCls", kTH1F, {axisNCls}); - histos.add(histodir + "/Lambda/hPosChi2PerNc", "hPosChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add(histodir + "/Lambda/hNegChi2PerNc", "hNegChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add(histodir + "/Lambda/hLifeTime", "hLifeTime", kTH1F, {axisLifetime}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hLambdapT", "hLambdapT", kTH1F, {axisPt}); - histos.add(histodir + "/Lambda/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); - histos.add(histodir + "/Lambda/h3dLambdaMass", "h3dLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); - histos.add(histodir + "/Lambda/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add(histodir + "/Lambda/hALambdapT", "hALambdapT", kTH1F, {axisPt}); - histos.add(histodir + "/Lambda/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); - histos.add(histodir + "/Lambda/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - - histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); - - histos.add(histodir + "/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/Sigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/Sigma0/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add(histodir + "/Sigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add(histodir + "/Sigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); - - histos.add(histodir + "/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/ASigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/ASigma0/hY", "hY", kTH1F, {axisRapidity}); - histos.add(histodir + "/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add(histodir + "/ASigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add(histodir + "/ASigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); - - // Process MC - if (doprocessMonteCarlo) { - histos.add(histodir + "/MC/Photon/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/Photon/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); - histos.add(histodir + "/MC/Photon/h2dPAVsPt", "h2dPAVsPt", kTH2F, {axisPA, axisPt}); - histos.add(histodir + "/MC/Photon/hPt_BadCollAssig", "hPt_BadCollAssig", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Photon/h2dPAVsPt_BadCollAssig", "h2dPAVsPt_BadCollAssig", kTH2F, {axisPA, axisPt}); - - histos.add(histodir + "/MC/Lambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/Lambda/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Lambda/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - - histos.add(histodir + "/MC/ALambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); - histos.add(histodir + "/MC/ALambda/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ALambda/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - - histos.add(histodir + "/MC/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); - - histos.add(histodir + "/MC/Sigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Sigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/Sigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/Sigma0/h2dMCPtVsGammaMCPt", "h2dMCPtVsGammaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/MC/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - - histos.add(histodir + "/MC/ASigma0/hPt", "hPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ASigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); - histos.add(histodir + "/MC/ASigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/ASigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2F, {axisPt, axisPt}); - histos.add(histodir + "/MC/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); - histos.add(histodir + "/MC/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - - // 1/pT Resolution: - if (fillpTResoQAhistos && histodir == "BeforeSel") { - histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/pTReso/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/pTReso/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + // setting CCDB service + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); + + // Event Counters + histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + + histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); + if (doPPAnalysis) { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); + } else { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); + } + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Below min IR"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(20, "Above max IR"); + + if (fGetIR) { + histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); + histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1D, {axisIRBinning}); + histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2D, {axisCentrality, axisIRBinning}); + } + + if (doprocessRealData || doprocessMonteCarlo) { + for (const auto& histodir : DirList) { + + histos.add(histodir + "/Photon/hTrackCode", "hTrackCode", kTH1D, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Photon/hV0Type", "hV0Type", kTH1D, {{8, 0.5f, 8.5f}}); + histos.add(histodir + "/Photon/hDCANegToPV", "hDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCAPosToPV", "hDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCADau", "hDCADau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Photon/hPosTPCCR", "hPosTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Photon/hNegTPCCR", "hNegTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Photon/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/Photon/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + + histos.add(histodir + "/Photon/hpT", "hpT", kTH1D, {axisPt}); + histos.add(histodir + "/Photon/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hPosEta", "hPosEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hNegEta", "hNegEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Photon/hRadius", "hRadius", kTH1D, {axisV0Radius}); + histos.add(histodir + "/Photon/hZ", "hZ", kTH1D, {axisZ}); + histos.add(histodir + "/Photon/h2dRZCut", "h2dRZCut", kTH2D, {axisZ, axisV0Radius}); + histos.add(histodir + "/Photon/h2dRZPlane", "h2dRZPlane", kTH2D, {axisZ, axisV0Radius}); + histos.add(histodir + "/Photon/hCosPA", "hCosPA", kTH1D, {axisCosPA}); + histos.add(histodir + "/Photon/hPsiPair", "hPsiPair", kTH1D, {axisPsiPair}); + histos.add(histodir + "/Photon/hPhi", "hPhi", kTH1D, {axisPhi}); + histos.add(histodir + "/Photon/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); + histos.add(histodir + "/Photon/hMass", "hMass", kTH1D, {axisPhotonMass}); + + histos.add(histodir + "/Lambda/hTrackCode", "hTrackCode", kTH1D, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Lambda/hRadius", "hRadius", kTH1D, {axisV0Radius}); + histos.add(histodir + "/Lambda/hDCADau", "hDCADau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Lambda/hCosPA", "hCosPA", kTH1D, {axisCosPA}); + histos.add(histodir + "/Lambda/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosEta", "hPosEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hNegEta", "hNegEta", kTH1D, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosTPCCR", "hPosTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Lambda/hNegTPCCR", "hNegTPCCR", kTH1D, {axisTPCrows}); + histos.add(histodir + "/Lambda/hPosITSCls", "hPosITSCls", kTH1D, {axisNCls}); + histos.add(histodir + "/Lambda/hNegITSCls", "hNegITSCls", kTH1D, {axisNCls}); + histos.add(histodir + "/Lambda/hPosChi2PerNc", "hPosChi2PerNc", kTH1D, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hNegChi2PerNc", "hNegChi2PerNc", kTH1D, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hLifeTime", "hLifeTime", kTH1D, {axisLifetime}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdapT", "hLambdapT", kTH1D, {axisPt}); + histos.add(histodir + "/Lambda/hLambdaMass", "hLambdaMass", kTH1D, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dLambdaMass", "h3dLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2D, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1D, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdapT", "hALambdapT", kTH1D, {axisPt}); + histos.add(histodir + "/Lambda/hAntiLambdaMass", "hAntiLambdaMass", kTH1D, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); + + histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2D, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/Sigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/Sigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/Sigma0/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/Sigma0/hRadius", "hRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/Sigma0/h2dRadiusVspT", "h2dRadiusVspT", kTH2D, {axisV0PairRadius, axisPt}); + histos.add(histodir + "/Sigma0/hDCAPairDau", "hDCAPairDau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/Sigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/Sigma0/h3dOPAngleVsMass", "h3dOPAngleVsMass", kTH3D, {{140, 0.0f, +7.0f}, axisPt, axisSigmaMass}); + + histos.add(histodir + "/ASigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/ASigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/ASigma0/hY", "hY", kTH1D, {axisRapidity}); + histos.add(histodir + "/ASigma0/hRadius", "hRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/ASigma0/h2dRadiusVspT", "h2dRadiusVspT", kTH2D, {axisV0PairRadius, axisPt}); + histos.add(histodir + "/ASigma0/hDCAPairDau", "hDCAPairDau", kTH1D, {axisDCAdau}); + histos.add(histodir + "/ASigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/ASigma0/h3dOPAngleVsMass", "h3dOPAngleVsMass", kTH3D, {{140, 0.0f, +7.0f}, axisPt, axisSigmaMass}); + + // Process MC + if (doprocessMonteCarlo) { + histos.add(histodir + "/MC/Photon/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Photon/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dPAVsPt", "h2dPAVsPt", kTH2D, {axisPA, axisPt}); + histos.add(histodir + "/MC/Photon/hPt_BadCollAssig", "hPt_BadCollAssig", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Photon/h2dPAVsPt_BadCollAssig", "h2dPAVsPt_BadCollAssig", kTH2D, {axisPA, axisPt}); + + histos.add(histodir + "/MC/Lambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Lambda/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Lambda/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/ALambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1D, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/ALambda/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ALambda/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3D, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/h2dArmenteros", "h2dArmenteros", kTH2D, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/MC/Sigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Sigma0/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/Sigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/MC/Sigma0/hMCProcess", "hMCProcess", kTH1D, {{50, -0.5f, 49.5f}}); + histos.add(histodir + "/MC/Sigma0/hGenRadius", "hGenRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCProcessVsGenRadius", "h2dMCProcessVsGenRadius", kTH2D, {{50, -0.5f, 49.5f}, axisV0PairRadius}); + histos.add(histodir + "/MC/Sigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/Sigma0/h3dMCProcess", "h3dMCProcess", kTH3D, {{50, -0.5f, 49.5f}, axisPt, axisSigmaMass}); + + histos.add(histodir + "/MC/ASigma0/hPt", "hPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ASigma0/hMCPt", "hMCPt", kTH1D, {axisPt}); + histos.add(histodir + "/MC/ASigma0/hMass", "hMass", kTH1D, {axisSigmaMass}); + histos.add(histodir + "/MC/ASigma0/hMCProcess", "hMCProcess", kTH1D, {{50, -0.5f, 49.5f}}); + histos.add(histodir + "/MC/ASigma0/hGenRadius", "hGenRadius", kTH1D, {axisV0PairRadius}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2D, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCProcessVsGenRadius", "h2dMCProcessVsGenRadius", kTH2D, {{50, -0.5f, 49.5f}, axisV0PairRadius}); + histos.add(histodir + "/MC/ASigma0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/ASigma0/h3dMCProcess", "h3dMCProcess", kTH3D, {{50, -0.5f, 49.5f}, axisPt, axisSigmaMass}); + + // 1/pT Resolution: + if (fillResoQAhistos && histodir == "BeforeSel") { + histos.add(histodir + "/MC/Reso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dSigma0RadiusResolution", "h2dSigma0RadiusResolution", kTH2D, {axisPt, axisDeltaPt}); + histos.add(histodir + "/MC/Reso/h2dASigma0RadiusResolution", "h2dASigma0RadiusResolution", kTH2D, {axisPt, axisDeltaPt}); + } + + // For background decomposition study + if (fillBkgQAhistos) { + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + } } + } + + // Selections + histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); + histos.add("Selection/Lambda/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); + + // For background decomposition study + if (fillBkgQAhistos && doprocessMonteCarlo) { + histos.add("BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + } + + for (size_t i = 0; i < PhotonSels.size(); ++i) { + const auto& sel = PhotonSels[i]; + + histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisPhotonMass}); + histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2D, {axisPt, axisSigmaMass}); + } + + for (size_t i = 0; i < LambdaSels.size(); ++i) { + const auto& sel = LambdaSels[i]; - // For background decomposition study - if (fillBkgQAhistos) { - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2F, {axisPt, axisSigmaMass}); - histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2F, {axisPt, axisSigmaMass}); + histos.add(Form("Selection/Lambda/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisLambdaMass}); + histos.get(HIST("Selection/Lambda/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dLambda%s", sel.c_str()), ("h2dLambda" + sel).c_str(), kTH2D, {axisPt, axisSigmaMass}); + } + } + + if (doprocessPi0RealData || doprocessPi0MonteCarlo) { + histos.add("Pi0/hMass", "hMass", kTH1D, {axisPi0Mass}); + histos.add("Pi0/hPt", "hPt", kTH1D, {axisPt}); + histos.add("Pi0/hY", "hY", kTH1D, {axisRapidity}); + histos.add("Pi0/h3dMass", "h3dMass", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); + histos.add("Pi0/h3dMass_MCAssociated", "h3dMass_MCAssociated", kTH3D, {axisCentrality, axisPt, axisPi0Mass}); + } + + if (doprocessGeneratedRun3 || doprocessPi0GeneratedRun3) { + + histos.add("Gen/hGenEvents", "hGenEvents", kTH2D, {{axisNch}, {2, -0.5f, +1.5f}}); + histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); + histos.get(HIST("Gen/hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); + + histos.add("Gen/hGenEventCentrality", "hGenEventCentrality", kTH1D, {axisCentrality}); + histos.add("Gen/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("Gen/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("Gen/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2D, {axisCentrality, axisNch}); + + histos.add("Gen/hEventPVzMC", "hEventPVzMC", kTH1D, {{100, -20.0f, +20.0f}}); + histos.add("Gen/hCentralityVsPVzMC", "hCentralityVsPVzMC", kTH2D, {{101, 0.0f, 101.0f}, {100, -20.0f, +20.0f}}); + + // Sigma0 specific + if (doprocessGeneratedRun3) { + histos.add("Gen/h2dGenSigma0", "h2dGenSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenAntiSigma0", "h2dGenAntiSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenSigma0VsMultMC_RecoedEvt", "h2dGenSigma0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenAntiSigma0VsMultMC_RecoedEvt", "h2dGenAntiSigma0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenSigma0VsMultMC", "h2dGenSigma0VsMultMC", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenAntiSigma0VsMultMC", "h2dGenAntiSigma0VsMultMC", kTH2D, {axisNch, axisPt}); + + } else { // Pi0 specific + histos.add("Gen/h2dGenPi0VsMultMC_RecoedEvt", "h2dGenPi0VsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("Gen/h2dGenPi0", "h2dGenPi0", kTH2D, {axisCentrality, axisPt}); + histos.add("Gen/h2dGenPi0VsMultMC", "h2dGenPi0VsMultMC", kTH2D, {axisNch, axisPt}); + } + } + } + + // ______________________________________________________ + // Check whether the collision passes our collision selections + // Should work with collisions, mccollisions, stracollisions and stramccollisions tables! + template + bool IsEventAccepted(TCollision const& collision, bool fillHists) + { + if (fillHists) + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (eventSelections.requireSel8 && !collision.sel8()) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); + if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); + if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); + if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); + if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); + if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); + if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); + if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); + if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); + if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); + if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); + if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); + if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); + } else { // we are in Pb-Pb + float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); + if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); + } + + // Fetch interaction rate only if required (in order to limit ccdb calls) + float interactionRate = (fGetIR) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + if (fGetIR) { + if (interactionRate < 0) + histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", collision.runNumber()), 1); // This lists all run numbers without IR info! + + histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); + histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); + } + + if (eventSelections.minIR >= 0 && interactionRate < eventSelections.minIR) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 18 /* Below min IR */); + + if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); + + // Fill centrality histogram after event selection + if (fillHists) + histos.fill(HIST("hEventCentrality"), centrality); + + return true; + } + + // ______________________________________________________ + // Simulated processing + // Return the list of indices to the recoed collision associated to a given MC collision. + template + std::vector getListOfRecoCollIndices(TMCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (auto const& collision : groupedCollisions) { + // consider event selections in the recoed <-> gen collision association, for the denominator (or numerator) of the efficiency (or signal loss)? + if (eventSelections.useEvtSelInDenomEff) { + if (!IsEventAccepted(collision, false)) { + continue; + } + } + // Find the collision with the biggest nbr of PV contributors + // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + bestCollisionIndex = collision.globalIndex(); } } + listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; } + return listBestCollisionIdx; + } - // Selections - histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); - histos.add("Selection/Lambda/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); + // ______________________________________________________ + // Simulated processing + // Fill generated event information (for event loss/splitting estimation) + template + void fillGeneratedEventProperties(TMCCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + // Apply selections on MC collisions + if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { + continue; + } + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { + continue; + } + + if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + continue; + } + } - for (size_t i = 0; i < PhotonSels.size(); ++i) { - const auto& sel = PhotonSels[i]; + histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); - histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisPhotonMass}); - histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); - histos.add(Form("Selection/Sigma0/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + // Check if there is at least one of the reconstructed collisions associated to this MC collision + // If so, we consider it + bool atLeastOne = false; + int biggestNContribs = -1; + float centrality = 100.5f; + int nCollisions = 0; + for (auto const& collision : groupedCollisions) { + + if (!IsEventAccepted(collision, false)) { + continue; + } + + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + } + + nCollisions++; + atLeastOne = true; + } + + histos.fill(HIST("Gen/hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); + histos.fill(HIST("Gen/hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); + histos.fill(HIST("Gen/hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); + histos.fill(HIST("Gen/hCentralityVsPVzMC"), centrality, mcCollision.posZ()); + histos.fill(HIST("Gen/hEventPVzMC"), mcCollision.posZ()); + + if (atLeastOne) { + histos.fill(HIST("Gen/hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); + histos.fill(HIST("Gen/hGenEventCentrality"), centrality); + } } + return; + } + + // ______________________________________________________ + // Simulated processing (subscribes to MC information too) + template + void analyzeGenerated(TMCCollisions const& mcCollisions, TCollisions const& collisions, TGenParticles const& genParticles) + { + fillGeneratedEventProperties(mcCollisions, collisions); + std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); + + for (auto& genParticle : genParticles) { + float centrality = 100.5f; - for (size_t i = 0; i < LambdaSels.size(); ++i) { - const auto& sel = LambdaSels[i]; + // Has MC collision + if (!genParticle.has_straMCCollision()) + continue; + + // Selection on the source (generator/transport) + if (!genParticle.producedByGenerator() && mc_keepOnlyFromGenerator) + continue; + + // Select corresponding mc collision && Basic event selection + auto mcCollision = genParticle.template straMCCollision_as>(); + if (eventSelections.applyZVtxSelOnMCPV && std::abs(mcCollision.posZ()) > eventSelections.maxZVtxPosition) { + continue; + } + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && mcCollision.multMCNParticlesEta10() < 1) { + continue; + } - histos.add(Form("Selection/Lambda/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisLambdaMass}); - histos.get(HIST("Selection/Lambda/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); - histos.add(Form("Selection/Sigma0/h2dLambda%s", sel.c_str()), ("h2dLambda" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + if (eventSelections.requireINEL1 && mcCollision.multMCNParticlesEta10() < 2) { + continue; + } + } + + //______________________________________________________________________________ + // Generated Sigma0 processing + if constexpr (requires { genParticle.sigma0MCPt(); }) { + + float ptmc = genParticle.sigma0MCPt(); + + if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { + auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + if (genParticle.isSigma0()) + histos.fill(HIST("Gen/h2dGenSigma0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + + else + histos.fill(HIST("Gen/h2dGenAntiSigma0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + + if (genParticle.isSigma0()) { + histos.fill(HIST("Gen/h2dGenSigma0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenSigma0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } else { + histos.fill(HIST("Gen/h2dGenAntiSigma0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenAntiSigma0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + } + //______________________________________________________________________________ + // Generated Pi0 processing + if constexpr (requires { genParticle.pi0MCPt(); }) { + float ptmc = genParticle.pi0MCPt(); + + if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { + auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); + centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("Gen/h2dGenPi0VsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + + histos.fill(HIST("Gen/h2dGenPi0"), centrality, ptmc); + histos.fill(HIST("Gen/h2dGenPi0VsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } } } //__________________________________________ - template - int retrieveV0TrackCode(TV0Object const& sigma) + template + int retrieveV0TrackCode(TSigma0Object const& sigma) { int TrkCode = 10; // 1: TPC-only, 2: TPC+Something, 3: ITS-Only, 4: ITS+TPC + Something, 10: anything else @@ -378,67 +862,69 @@ struct sigmaanalysis { return TrkCode; } - template - void getpTResolution(TV0Object const& sigma) + template + void getResolution(TSigma0Object const& sigma) { //_______________________________________ // Gamma MC association - if (sigma.photonCandPDGCode() == 22) { - if (sigma.photonMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h2dGammaPtResolution"), 1.f / sigma.photonMCPt(), 1.f / sigma.photonPt() - 1.f / sigma.photonMCPt()); // pT resolution + if (sigma.photonPDGCode() == 22) { + if (sigma.photonmcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h2dGammaPtResolution"), 1.f / sigma.photonmcpt(), 1.f / sigma.photonPt() - 1.f / sigma.photonmcpt()); // pT resolution } } //_______________________________________ // Lambda MC association - if (sigma.lambdaCandPDGCode() == 3122) { - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h2dLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + if (sigma.lambdaPDGCode() == 3122) { + if (sigma.lambdamcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dLambdaPtResolution"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution } } //_______________________________________ // AntiLambda MC association - if (sigma.lambdaCandPDGCode() == -3122) { - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + if (sigma.lambdaPDGCode() == -3122) { + if (sigma.lambdamcpt() > 0) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt()); // pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/Reso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdamcpt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdamcpt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution } } //_______________________________________ // Sigma and AntiSigma MC association - if (sigma.isSigma()) { - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("BeforeSel/MC/pTReso/h2dSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution + if (sigma.isSigma0()) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dSigma0RadiusResolution"), sigma.mcpt(), sigma.radius() - sigma.mcradius()); // pT resolution + if (sigma.mcpt() > 0) + histos.fill(HIST("BeforeSel/MC/Reso/h2dSigma0PtResolution"), 1.f / sigma.mcpt(), 1.f / sigma.pt() - 1.f / sigma.mcpt()); // pT resolution } - if (sigma.isAntiSigma()) { - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution + if (sigma.isAntiSigma0()) { + histos.fill(HIST("BeforeSel/MC/Reso/h2dASigma0RadiusResolution"), sigma.mcpt(), sigma.radius() - sigma.mcradius()); // pT resolution + if (sigma.mcpt() > 0) + histos.fill(HIST("BeforeSel/MC/Reso/h2dAntiSigma0PtResolution"), 1.f / sigma.mcpt(), 1.f / sigma.pt() - 1.f / sigma.mcpt()); // pT resolution } } // To save histograms for background analysis - template - void runBkgAnalysis(TV0Object const& sigma) + template + void runBkgAnalysis(TSigma0Object const& sigma) { // Check whether it is before or after selections static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; - bool fIsSigma = sigma.isSigma(); - bool fIsAntiSigma = sigma.isAntiSigma(); - int PhotonPDGCode = sigma.photonCandPDGCode(); - int PhotonPDGCodeMother = sigma.photonCandPDGCodeMother(); - int LambdaPDGCode = sigma.lambdaCandPDGCode(); - int LambdaPDGCodeMother = sigma.lambdaCandPDGCodeMother(); - float sigmapT = sigma.sigmapT(); - float sigmaMass = sigma.sigmaMass(); + bool fIsSigma = sigma.isSigma0(); + bool fIsAntiSigma = sigma.isAntiSigma0(); + int PhotonPDGCode = sigma.photonPDGCode(); + int PhotonPDGCodeMother = sigma.photonPDGCodeMother(); + int LambdaPDGCode = sigma.lambdaPDGCode(); + int LambdaPDGCodeMother = sigma.lambdaPDGCodeMother(); + float sigmapT = sigma.pt(); + float sigmaMass = sigma.sigma0Mass(); histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); @@ -465,35 +951,31 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); } - template - void fillQAHistos(TV0Object const& sigma) + template + void fillHistos(TSigma0Object const& sigma, TCollision const& collision) { // Check whether it is before or after selections - // static std::string main_dir; - // main_dir = IsBeforeSel ? "BeforeSel" : "AfterSel"; static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; // Get V0trackCode int GammaTrkCode = retrieveV0TrackCode(sigma); int LambdaTrkCode = retrieveV0TrackCode(sigma); - float photonRZLineCut = TMath::Abs(sigma.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; + float photonRZLineCut = TMath::Abs(sigma.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); //_______________________________________ // Photon histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hTrackCode"), GammaTrkCode); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hV0Type"), sigma.photonV0Type()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegpT"), sigma.photonNegPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPospT"), sigma.photonPosPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCANegToPV"), sigma.photonDCANegPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCAPosToPV"), sigma.photonDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCADau"), sigma.photonDCADau()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosTPCCR"), sigma.photonPosTPCCrossedRows()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegTPCCR"), sigma.photonNegTPCCrossedRows()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosTPCNSigmaEl"), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegTPCNSigmaEl"), sigma.photonNegTPCNSigmaEl()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hpT"), sigma.photonPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hY"), sigma.photonY()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosEta"), sigma.photonPosEta()); @@ -505,7 +987,7 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hCosPA"), sigma.photonCosPA()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPsiPair"), sigma.photonPsiPair()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPhi"), sigma.photonPhi()); - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h3dMass"), sigma.sigmaCentrality(), sigma.photonPt(), sigma.photonMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h3dMass"), centrality, sigma.photonPt(), sigma.photonMass()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hMass"), sigma.photonMass()); //_______________________________________ @@ -537,14 +1019,16 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdapT"), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaMass"), sigma.lambdaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.lambdaMass()); - - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hY"), sigma.sigmaRapidity()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dLambdaMass"), centrality, sigma.lambdaPt(), sigma.lambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hY"), sigma.sigma0Y()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hRadius"), sigma.radius()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h2dRadiusVspT"), sigma.radius(), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hDCAPairDau"), sigma.dcadaughters()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dMass"), centrality, sigma.pt(), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dOPAngleVsMass"), sigma.opAngle(), sigma.pt(), sigma.sigma0Mass()); } else { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma()); @@ -552,87 +1036,98 @@ struct sigmaanalysis { histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdapT"), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hAntiLambdaMass"), sigma.antilambdaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dAntiLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.antilambdaMass()); - - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hY"), sigma.sigmaRapidity()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dAntiLambdaMass"), centrality, sigma.lambdaPt(), sigma.antilambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hY"), sigma.sigma0Y()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hRadius"), sigma.radius()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h2dRadiusVspT"), sigma.radius(), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hDCAPairDau"), sigma.dcadaughters()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dMass"), centrality, sigma.pt(), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dOPAngleVsMass"), sigma.opAngle(), sigma.pt(), sigma.sigma0Mass()); } //_______________________________________ // MC specific if (doprocessMonteCarlo) { - if constexpr (requires { sigma.lambdaCandPDGCode(); sigma.photonCandPDGCode(); }) { + if constexpr (requires { sigma.lambdaPDGCode(); sigma.photonPDGCode(); }) { //_______________________________________ // Gamma MC association - if (sigma.photonCandPDGCode() == 22) { + if (sigma.photonPDGCode() == 22) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hV0ToCollAssoc"), sigma.photonIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt"), sigma.photonPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hMCPt"), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hMCPt"), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPosTPCNSigmaEl"), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hNegTPCNSigmaEl"), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); - - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt"), TMath::ACos(sigma.photonCosPA()), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt"), TMath::ACos(sigma.photonCosPA()), sigma.photonmcpt()); if (!sigma.photonIsCorrectlyAssoc()) { - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt_BadCollAssig"), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt_BadCollAssig"), TMath::ACos(sigma.photonCosPA()), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt_BadCollAssig"), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPAVsPt_BadCollAssig"), TMath::ACos(sigma.photonCosPA()), sigma.photonmcpt()); } } //_______________________________________ // Lambda MC association - if (sigma.lambdaCandPDGCode() == 3122) { + if (sigma.lambdaPDGCode() == 3122) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hPt"), sigma.lambdaPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hMCPt"), sigma.lambdamcpt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.lambdaPt()); } //_______________________________________ // AntiLambda MC association - if (sigma.lambdaCandPDGCode() == -3122) { + if (sigma.lambdaPDGCode() == -3122) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hPt"), sigma.lambdaPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hMCPt"), sigma.lambdamcpt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma(), sigma.lambdaPt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma(), sigma.lambdaPt()); } //_______________________________________ // Sigma0 MC association - if (sigma.isSigma()) { + if (sigma.isSigma0()) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCPt"), sigma.sigmaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsGammaMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCPt"), sigma.mcpt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsLambdaMCPt"), sigma.mcpt(), sigma.lambdamcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsPhotonMCPt"), sigma.mcpt(), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMass"), centrality, sigma.mcpt(), sigma.sigma0Mass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCProcess"), sigma.mcprocess()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hGenRadius"), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCProcessVsGenRadius"), sigma.mcprocess(), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMCProcess"), sigma.mcprocess(), sigma.mcpt(), sigma.sigma0Mass()); } //_______________________________________ // AntiSigma0 MC association - if (sigma.isAntiSigma()) { + if (sigma.isAntiSigma0()) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hPt"), sigma.sigmapT()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCPt"), sigma.sigmaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsPhotonMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMass"), sigma.sigmaMass()); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hPt"), sigma.pt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCPt"), sigma.mcpt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsLambdaMCPt"), sigma.mcpt(), sigma.lambdamcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsPhotonMCPt"), sigma.mcpt(), sigma.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMass"), sigma.sigma0Mass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMass"), centrality, sigma.mcpt(), sigma.sigma0Mass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCProcess"), sigma.mcprocess()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hGenRadius"), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCProcessVsGenRadius"), sigma.mcprocess(), sigma.mcradius()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMCProcess"), sigma.mcprocess(), sigma.mcpt(), sigma.sigma0Mass()); } // For background studies: @@ -641,17 +1136,17 @@ struct sigmaanalysis { //_______________________________________ // pT resolution histos - if ((mode == 0) && fillpTResoQAhistos) - getpTResolution(sigma); + if ((mode == 0) && fillResoQAhistos) + getResolution(sigma); } } } - template - void fillSelHistos(TV0Object const& sigma, int PDGRequired) + template + void fillSelHistos(TSigma0Object const& sigma, int PDGRequired) { - static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DaupT", "DCADauToPV", + static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; @@ -664,7 +1159,7 @@ struct sigmaanalysis { if constexpr (selection_index >= 0 && selection_index < (int)std::size(PhotonSelsLocal)) { histos.fill(HIST("Selection/Photon/hCandidateSel"), selection_index); histos.fill(HIST("Selection/Photon/h2d") + HIST(PhotonSelsLocal[selection_index]), sigma.photonPt(), sigma.photonMass()); - histos.fill(HIST("Selection/Sigma0/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("Selection/Sigma0/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), sigma.pt(), sigma.sigma0Mass()); } } @@ -672,7 +1167,7 @@ struct sigmaanalysis { if constexpr (selection_index >= 0 && selection_index < (int)std::size(LambdaSelsLocal)) { histos.fill(HIST("Selection/Lambda/hCandidateSel"), selection_index); histos.fill(HIST("Selection/Lambda/h2d") + HIST(LambdaSelsLocal[selection_index]), sigma.lambdaPt(), sigma.lambdaMass()); - histos.fill(HIST("Selection/Sigma0/h2dLambda") + HIST(LambdaSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("Selection/Sigma0/h2dLambda") + HIST(LambdaSelsLocal[selection_index]), sigma.pt(), sigma.sigma0Mass()); } } } @@ -682,73 +1177,69 @@ struct sigmaanalysis { bool selectPhoton(TV0Object const& cand) { fillSelHistos<0>(cand, 22); - if (cand.photonV0Type() != Photonv0TypeSel && Photonv0TypeSel > -1) + if (cand.photonV0Type() != photonSelections.Photonv0TypeSel && photonSelections.Photonv0TypeSel > -1) return false; fillSelHistos<1>(cand, 22); - if ((cand.photonPosPt() < PhotonDauMinPt) || (cand.photonNegPt() < PhotonDauMinPt)) + if ((TMath::Abs(cand.photonDCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < photonSelections.PhotonMinDCADauToPv)) return false; fillSelHistos<2>(cand, 22); - if ((TMath::Abs(cand.photonDCAPosPV()) < PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < PhotonMinDCADauToPv)) + if (TMath::Abs(cand.photonDCADau()) > photonSelections.PhotonMaxDCAV0Dau) return false; fillSelHistos<3>(cand, 22); - if (TMath::Abs(cand.photonDCADau()) > PhotonMaxDCAV0Dau) + if ((cand.photonPosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows)) return false; fillSelHistos<4>(cand, 22); - if ((cand.photonPosTPCCrossedRows() < PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < PhotonMinTPCCrossedRows)) + if (((cand.photonPosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) return false; - fillSelHistos<5>(cand, 22); - if (((cand.photonPosTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > PhotonMaxTPCNSigmas))) + if (((cand.photonNegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) return false; - if (((cand.photonNegTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > PhotonMaxTPCNSigmas))) + fillSelHistos<5>(cand, 22); + if ((cand.photonPt() < photonSelections.PhotonMinPt) || (cand.photonPt() > photonSelections.PhotonMaxPt)) return false; fillSelHistos<6>(cand, 22); - if ((cand.photonPt() < PhotonMinPt) || (cand.photonPt() > PhotonMaxPt)) + if ((TMath::Abs(cand.photonY()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > photonSelections.PhotonMaxDauEta)) return false; fillSelHistos<7>(cand, 22); - if ((TMath::Abs(cand.photonY()) > PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > PhotonMaxDauEta)) + if ((cand.photonRadius() < photonSelections.PhotonMinRadius) || (cand.photonRadius() > photonSelections.PhotonMaxRadius)) return false; fillSelHistos<8>(cand, 22); - if ((cand.photonRadius() < PhotonMinRadius) || (cand.photonRadius() > PhotonMaxRadius)) + float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; + if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > photonSelections.PhotonMaxZ)) return false; fillSelHistos<9>(cand, 22); - float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; - if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > PhotonMaxZ)) + if (cand.photonQt() > photonSelections.PhotonMaxQt) return false; - fillSelHistos<10>(cand, 22); - if (cand.photonQt() > PhotonMaxQt) + if (TMath::Abs(cand.photonAlpha()) > photonSelections.PhotonMaxAlpha) return false; - if (TMath::Abs(cand.photonAlpha()) > PhotonMaxAlpha) + fillSelHistos<10>(cand, 22); + if (cand.photonCosPA() < photonSelections.PhotonMinV0cospa) return false; fillSelHistos<11>(cand, 22); - if (cand.photonCosPA() < PhotonMinV0cospa) + if (TMath::Abs(cand.photonPsiPair()) > photonSelections.PhotonPsiPairMax) return false; fillSelHistos<12>(cand, 22); - if (TMath::Abs(cand.photonPsiPair()) > PhotonPsiPairMax) + if ((((cand.photonPhi() > photonSelections.PhotonPhiMin1) && (cand.photonPhi() < photonSelections.PhotonPhiMax1)) || ((cand.photonPhi() > photonSelections.PhotonPhiMin2) && (cand.photonPhi() < photonSelections.PhotonPhiMax2))) && ((photonSelections.PhotonPhiMin1 != -1) && (photonSelections.PhotonPhiMax1 != -1) && (photonSelections.PhotonPhiMin2 != -1) && (photonSelections.PhotonPhiMax2 != -1))) return false; fillSelHistos<13>(cand, 22); - if ((((cand.photonPhi() > PhotonPhiMin1) && (cand.photonPhi() < PhotonPhiMax1)) || ((cand.photonPhi() > PhotonPhiMin2) && (cand.photonPhi() < PhotonPhiMax2))) && ((PhotonPhiMin1 != -1) && (PhotonPhiMax1 != -1) && (PhotonPhiMin2 != -1) && (PhotonPhiMax2 != -1))) + if (TMath::Abs(cand.photonMass()) > photonSelections.PhotonMaxMass) return false; fillSelHistos<14>(cand, 22); - if (TMath::Abs(cand.photonMass()) > PhotonMaxMass) - return false; - - fillSelHistos<15>(cand, 22); return true; } @@ -757,68 +1248,68 @@ struct sigmaanalysis { bool selectLambda(TV0Object const& cand) { fillSelHistos<0>(cand, 3122); - if ((cand.lambdaRadius() < LambdaMinv0radius) || (cand.lambdaRadius() > LambdaMaxv0radius)) + if ((cand.lambdaRadius() < lambdaSelections.LambdaMinv0radius) || (cand.lambdaRadius() > lambdaSelections.LambdaMaxv0radius)) return false; fillSelHistos<1>(cand, 3122); - if (TMath::Abs(cand.lambdaDCADau()) > LambdaMaxDCAV0Dau) + if (TMath::Abs(cand.lambdaDCADau()) > lambdaSelections.LambdaMaxDCAV0Dau) return false; fillSelHistos<2>(cand, 3122); - if ((cand.lambdaQt() < LambdaMinQt) || (cand.lambdaQt() > LambdaMaxQt)) + if ((cand.lambdaQt() < lambdaSelections.LambdaMinQt) || (cand.lambdaQt() > lambdaSelections.LambdaMaxQt)) return false; - if ((TMath::Abs(cand.lambdaAlpha()) < LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > LambdaMaxAlpha)) + if ((TMath::Abs(cand.lambdaAlpha()) < lambdaSelections.LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > lambdaSelections.LambdaMaxAlpha)) return false; fillSelHistos<3>(cand, 3122); - if (cand.lambdaCosPA() < LambdaMinv0cospa) + if (cand.lambdaCosPA() < lambdaSelections.LambdaMinv0cospa) return false; fillSelHistos<4>(cand, 3122); - if ((TMath::Abs(cand.lambdaY()) > LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > LambdaMaxDauEta)) + if ((TMath::Abs(cand.lambdaY()) > lambdaSelections.LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > lambdaSelections.LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > lambdaSelections.LambdaMaxDauEta)) return false; fillSelHistos<5>(cand, 3122); - if ((cand.lambdaPosTPCCrossedRows() < LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < LambdaMinTPCCrossedRows)) + if ((cand.lambdaPosTPCCrossedRows() < lambdaSelections.LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < lambdaSelections.LambdaMinTPCCrossedRows)) return false; fillSelHistos<6>(cand, 3122); // check minimum number of ITS clusters + reject ITS afterburner tracks if requested bool posIsFromAfterburner = cand.lambdaPosChi2PerNcl() < 0; bool negIsFromAfterburner = cand.lambdaNegChi2PerNcl() < 0; - if (cand.lambdaPosITSCls() < LambdaMinITSclusters && (!LambdaRejectPosITSafterburner || posIsFromAfterburner)) + if (cand.lambdaPosITSCls() < lambdaSelections.LambdaMinITSclusters && (!lambdaSelections.LambdaRejectPosITSafterburner || posIsFromAfterburner)) return false; - if (cand.lambdaNegITSCls() < LambdaMinITSclusters && (!LambdaRejectNegITSafterburner || negIsFromAfterburner)) + if (cand.lambdaNegITSCls() < lambdaSelections.LambdaMinITSclusters && (!lambdaSelections.LambdaRejectNegITSafterburner || negIsFromAfterburner)) return false; fillSelHistos<7>(cand, 3122); - if (cand.lambdaLifeTime() > LambdaMaxLifeTime) + if (cand.lambdaLifeTime() > lambdaSelections.LambdaMaxLifeTime) return false; // Separating lambda and antilambda selections: fillSelHistos<8>(cand, 3122); if (cand.lambdaAlpha() > 0) { // Lambda selection // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > lambdaSelections.LambdaPrMaxTOFNSigmas)) return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > lambdaSelections.LambdaPiMaxTOFNSigmas)) return false; // DCA Selection fillSelHistos<9>(cand, 3122); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < LambdaMinDCANegToPv)) + if ((TMath::Abs(cand.lambdaDCAPosPV()) < lambdaSelections.LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < lambdaSelections.LambdaMinDCANegToPv)) return false; // Mass Selection fillSelHistos<10>(cand, 3122); - if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > lambdaSelections.LambdaWindow) return false; fillSelHistos<11>(cand, 3122); @@ -826,25 +1317,25 @@ struct sigmaanalysis { } else { // AntiLambda selection // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > LambdaMaxTPCNSigmas)) + if (lambdaSelections.fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > lambdaSelections.LambdaMaxTPCNSigmas)) return false; // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > lambdaSelections.LambdaPrMaxTOFNSigmas)) return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) + if (lambdaSelections.fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > lambdaSelections.LambdaPiMaxTOFNSigmas)) return false; // DCA Selection fillSelHistos<9>(cand, 3122); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < ALambdaMinDCANegToPv)) + if ((TMath::Abs(cand.lambdaDCAPosPV()) < lambdaSelections.ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < lambdaSelections.ALambdaMinDCANegToPv)) return false; // Mass Selection fillSelHistos<10>(cand, 3122); - if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > lambdaSelections.LambdaWindow) return false; fillSelHistos<11>(cand, 3122); @@ -854,85 +1345,254 @@ struct sigmaanalysis { } // Apply selections in sigma0 candidates - template - bool processSigmaCandidate(TV0Object const& cand) + template + bool processSigma0Candidate(TSigma0Object const& cand) { + // Photon specific selections + if (!selectPhoton(cand)) + return false; - // Do ML analysis - if (fUseMLSel) { - if ((cand.gammaBDTScore() == -1) || (cand.lambdaBDTScore() == -1) || (cand.antilambdaBDTScore() == -1)) { - LOGF(fatal, "ML Score is not available! Please, enable gamma and lambda selection with ML in sigmabuilder!"); - } - // Photon selection: - if (cand.gammaBDTScore() <= Gamma_MLThreshold) - return false; + // Lambda specific selections + if (!selectLambda(cand)) + return false; - // Lambda selection: - if (cand.lambdaBDTScore() <= Lambda_MLThreshold) + // Sigma0 specific selections + // Rapidity + if constexpr (requires { cand.sigma0MCY(); }) { // MC + if (TMath::Abs(cand.sigma0MCY()) > sigma0Selections.Sigma0MaxRap) return false; - - // AntiLambda selection: - if (cand.antilambdaBDTScore() <= AntiLambda_MLThreshold) + } else { // Real data + if (TMath::Abs(cand.sigma0Y()) > sigma0Selections.Sigma0MaxRap) return false; + } + + // V0Pair Radius + if (cand.radius() > sigma0Selections.Sigma0MaxRadius) + return false; + + // DCA V0Pair Daughters + if (cand.dcadaughters() > sigma0Selections.Sigma0MaxDCADau) + return false; + // Opening Angle + if (cand.opAngle() > sigma0Selections.Sigma0MaxOPAngle) + return false; + + return true; + } + + // Main analysis function + template + void analyzeRecoeSigma0s(TCollisions const& collisions, TSigma0s const& fullSigma0s) + { + // Custom grouping + std::vector> sigma0grouped(collisions.size()); + + for (const auto& sigma0 : fullSigma0s) { + sigma0grouped[sigma0.straCollisionId()].push_back(sigma0.globalIndex()); } - // Go for standard analysis - else { + // Collisions loop + for (const auto& coll : collisions) { - // Photon specific selections - if (!selectPhoton(cand)) - return false; + // Event selection + if (!IsEventAccepted(coll, true)) + continue; - // Lambda specific selections - if (!selectLambda(cand)) - return false; + // Sigma0s loop + for (size_t i = 0; i < sigma0grouped[coll.globalIndex()].size(); i++) { + auto sigma0 = fullSigma0s.rawIteratorAt(sigma0grouped[coll.globalIndex()][i]); + + // if MC + if constexpr (requires { sigma0.isSigma0(); sigma0.isAntiSigma0(); }) { + if (doMCAssociation && !(sigma0.isSigma0() || sigma0.isAntiSigma0())) + continue; + + if (selRecoFromGenerator && !sigma0.isProducedByGenerator()) + continue; + } + + // Fill histos before any selection + fillHistos<0>(sigma0, coll); + + // Select sigma0 candidates + if (!processSigma0Candidate(sigma0)) + continue; + + // Fill histos after all selections + fillHistos<1>(sigma0, coll); + } + } + } + + // Apply selections in sigma0 candidates + template + bool processPi0Candidate(TPi0Object const& cand) + { + if ((cand.photon1V0Type() != photonSelections.Photonv0TypeSel || cand.photon2V0Type() != photonSelections.Photonv0TypeSel) && photonSelections.Photonv0TypeSel > -1) + return false; + + if ((TMath::Abs(cand.photon1DCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon2DCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon1DCANegPV()) < photonSelections.PhotonMinDCADauToPv) || + (TMath::Abs(cand.photon2DCANegPV()) < photonSelections.PhotonMinDCADauToPv)) + return false; + + if ((TMath::Abs(cand.photon1DCADau()) > photonSelections.PhotonMaxDCAV0Dau) || (TMath::Abs(cand.photon2DCADau()) > photonSelections.PhotonMaxDCAV0Dau)) + return false; + + if ((cand.photon1PosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon2PosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon1NegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || + (cand.photon2NegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows)) + return false; + + if (((cand.photon1PosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon1PosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas)) || + ((cand.photon2PosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon2PosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + return false; + + if (((cand.photon1NegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon1NegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas)) || + ((cand.photon2NegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || + (cand.photon2NegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + return false; + + if (((cand.photon1Pt() < photonSelections.PhotonMinPt) || + (cand.photon1Pt() > photonSelections.PhotonMaxPt)) || + ((cand.photon2Pt() < photonSelections.PhotonMinPt) || + (cand.photon2Pt() > photonSelections.PhotonMaxPt))) + return false; + + if ((TMath::Abs(cand.photon1Y()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photon1PosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photon1NegEta()) > photonSelections.PhotonMaxDauEta)) + return false; + + if ((TMath::Abs(cand.photon2Y()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photon2PosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photon2NegEta()) > photonSelections.PhotonMaxDauEta)) + return false; + + if (((cand.photon1Radius() < photonSelections.PhotonMinRadius) || (cand.photon1Radius() > photonSelections.PhotonMaxRadius)) || + ((cand.photon2Radius() < photonSelections.PhotonMinRadius) || (cand.photon2Radius() > photonSelections.PhotonMaxRadius))) + return false; + + if ((cand.photon1Qt() > photonSelections.PhotonMaxQt) || cand.photon2Qt() > photonSelections.PhotonMaxQt) + return false; + + if ((TMath::Abs(cand.photon1Alpha()) > photonSelections.PhotonMaxAlpha) || (TMath::Abs(cand.photon2Alpha()) > photonSelections.PhotonMaxAlpha)) + return false; + + if ((cand.photon1CosPA() < photonSelections.PhotonMinV0cospa) || (cand.photon2CosPA() < photonSelections.PhotonMinV0cospa)) + return false; - // Sigma0 specific selections - if (TMath::Abs(cand.sigmaRapidity()) > SigmaMaxRap) + if ((TMath::Abs(cand.photon1Mass()) > photonSelections.PhotonMaxMass) || (TMath::Abs(cand.photon2Mass()) > photonSelections.PhotonMaxMass)) + return false; + + // Pi0 specific selections + if constexpr (requires { cand.pi0MCY(); }) { // MC + if (TMath::Abs(cand.pi0MCY()) > pi0Selections.Pi0MaxRap) + return false; + } else { // DATA + if (TMath::Abs(cand.pi0Y()) > pi0Selections.Pi0MaxRap) return false; } + // V0Pair Radius + if (cand.radius() > pi0Selections.Pi0MaxRadius) + return false; + + // DCA V0Pair Daughters + if (cand.dcadaughters() > pi0Selections.Pi0MaxDCADau) + return false; + return true; } - void processMonteCarlo(V0MCSigmas const& sigmas) + // Main Pi0 QA analysis function + template + void analyzeRecoePi0s(TCollisions const& collisions, TPi0s const& fullPi0s) { - for (auto& sigma : sigmas) { // selecting Sigma0-like candidates - if (doMCAssociation && !(sigma.isSigma() || sigma.isAntiSigma())) { - continue; - } + // Custom grouping + std::vector> pi0grouped(collisions.size()); - // Fill histos before any selection - fillQAHistos<0>(sigma); + for (const auto& pi0 : fullPi0s) { + pi0grouped[pi0.straCollisionId()].push_back(pi0.globalIndex()); + } + + // Collisions loop + for (const auto& coll : collisions) { - // Select sigma0 candidates - if (!processSigmaCandidate(sigma)) + // Event selection + if (!IsEventAccepted(coll, true)) continue; - // Fill histos after all selections - fillQAHistos<1>(sigma); + // Pi0s loop + float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); + + for (size_t i = 0; i < pi0grouped[coll.globalIndex()].size(); i++) { + auto pi0 = fullPi0s.rawIteratorAt(pi0grouped[coll.globalIndex()][i]); + + // Select sigma0 candidates + if (!processPi0Candidate(pi0)) + continue; + + // If MC + if constexpr (requires { pi0.isPi0(); }) { + if (selRecoFromGenerator && !pi0.isProducedByGenerator()) + continue; + + if (pi0.isPi0()) + histos.fill(HIST("Pi0/h3dMass_MCAssociated"), centrality, pi0.mcpt(), pi0.pi0Mass()); + } + + // Fill histos after all selections + histos.fill(HIST("Pi0/hMass"), pi0.pi0Mass()); + histos.fill(HIST("Pi0/hPt"), pi0.pt()); + histos.fill(HIST("Pi0/hY"), pi0.pi0Y()); + histos.fill(HIST("Pi0/h3dMass"), centrality, pi0.pt(), pi0.pi0Mass()); + } } } - void processRealData(V0Sigmas const& sigmas) + void processRealData(soa::Join const& collisions, Sigma0s const& fullSigma0s) { - for (auto& sigma : sigmas) { // selecting Sigma0-like candidates + analyzeRecoeSigma0s(collisions, fullSigma0s); + } - // Fill histos before any selection - fillQAHistos<0>(sigma); + void processMonteCarlo(soa::Join const& collisions, MCSigma0s const& fullSigma0s) + { + analyzeRecoeSigma0s(collisions, fullSigma0s); + } - // Select sigma0 candidates - if (!processSigmaCandidate(sigma)) - continue; + // Simulated processing in Run 3 + void processGeneratedRun3(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& Sigma0Gens) + { + analyzeGenerated(mcCollisions, collisions, Sigma0Gens); + } - // Fill histos after all selections - fillQAHistos<1>(sigma); - } + // _____________________________________________________ + // Pi0 QA + void processPi0RealData(soa::Join const& collisions, soa::Join const& fullPi0s) + { + analyzeRecoePi0s(collisions, fullPi0s); } - PROCESS_SWITCH(sigmaanalysis, processMonteCarlo, "Do Monte-Carlo-based analysis", false); + void processPi0MonteCarlo(soa::Join const& collisions, soa::Join const& fullPi0s) + { + analyzeRecoePi0s(collisions, fullPi0s); + } + + void processPi0GeneratedRun3(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& Pi0Gens) + { + analyzeGenerated(mcCollisions, collisions, Pi0Gens); + } + + // _____________________________________________________ PROCESS_SWITCH(sigmaanalysis, processRealData, "Do real data analysis", true); + PROCESS_SWITCH(sigmaanalysis, processMonteCarlo, "Do Monte-Carlo-based analysis", false); + PROCESS_SWITCH(sigmaanalysis, processGeneratedRun3, "process MC generated Run 3", false); + PROCESS_SWITCH(sigmaanalysis, processPi0RealData, "Do real data analysis for pi0 QA", false); + PROCESS_SWITCH(sigmaanalysis, processPi0MonteCarlo, "Do Monte-Carlo-based analysis for pi0 QA", false); + PROCESS_SWITCH(sigmaanalysis, processPi0GeneratedRun3, "process MC generated Run 3 for pi0 QA", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)