diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 5cad9c8fc0a..e890ffc030b 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -129,6 +129,8 @@ struct strangederivedbuilder { ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "p_{T} (GeV/c)"}; ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, "Centrality"}; + ConfigurableAxis axisRawCentrality{"axisRawCentrality", {VARIABLE_WIDTH, 0.000f, 52.320f, 75.400f, 95.719f, 115.364f, 135.211f, 155.791f, 177.504f, 200.686f, 225.641f, 252.645f, 281.906f, 313.850f, 348.302f, 385.732f, 426.307f, 470.146f, 517.555f, 568.899f, 624.177f, 684.021f, 748.734f, 818.078f, 892.577f, 973.087f, 1058.789f, 1150.915f, 1249.319f, 1354.279f, 1465.979f, 1584.790f, 1710.778f, 1844.863f, 1985.746f, 2134.643f, 2291.610f, 2456.943f, 2630.653f, 2813.959f, 3006.631f, 3207.229f, 3417.641f, 3637.318f, 3865.785f, 4104.997f, 4354.938f, 4615.786f, 4885.335f, 5166.555f, 5458.021f, 5762.584f, 6077.881f, 6406.834f, 6746.435f, 7097.958f, 7462.579f, 7839.165f, 8231.629f, 8635.640f, 9052.000f, 9484.268f, 9929.111f, 10389.350f, 10862.059f, 11352.185f, 11856.823f, 12380.371f, 12920.401f, 13476.971f, 14053.087f, 14646.190f, 15258.426f, 15890.617f, 16544.433f, 17218.024f, 17913.465f, 18631.374f, 19374.983f, 20136.700f, 20927.783f, 21746.796f, 22590.880f, 23465.734f, 24372.274f, 25314.351f, 26290.488f, 27300.899f, 28347.512f, 29436.133f, 30567.840f, 31746.818f, 32982.664f, 34276.329f, 35624.859f, 37042.588f, 38546.609f, 40139.742f, 41837.980f, 43679.429f, 45892.130f, 400000.000f}, "raw centrality signal"}; // for QA + ConfigurableAxis axisNVertices{"axisNVertices", {10, -0.5f, 9.5f}, "N(vertices)"}; Configurable fillEmptyCollisions{"fillEmptyCollisions", false, "fill collision entries without candidates"}; @@ -144,6 +146,8 @@ struct strangederivedbuilder { Configurable fillRawFV0A{"fillRawFV0A", false, "Fill raw FV0A information for debug"}; Configurable fillRawNTracksEta1{"fillRawNTracksEta1", true, "Fill raw NTracks |eta|<1 information for debug"}; + Configurable qaCentrality{"qaCentrality", false, "qa centrality flag: check base raw values"}; + // For manual sliceBy Preslice V0perCollision = o2::aod::v0data::collisionId; Preslice CascperCollision = o2::aod::cascdata::collisionId; @@ -180,6 +184,14 @@ struct strangederivedbuilder { } histos.add("h2dNVerticesVsCentrality", "h2dNVerticesVsCentrality", kTH2D, {axisCentrality, axisNVertices}); + + // for QA and test purposes + auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); + + for (int ii = 1; ii < 101; ii++) { + float value = 100.5f - static_cast(ii); + hRawCentrality->SetBinContent(ii, value); + } } void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) @@ -213,6 +225,13 @@ struct strangederivedbuilder { { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); + + float centrality = collision.centFT0C(); + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); + } + auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx); auto CascTable_thisColl = Cascades.sliceBy(CascperCollision, collIdx); auto KFCascTable_thisColl = KFCascades.sliceBy(KFCascperCollision, collIdx); @@ -225,7 +244,7 @@ struct strangederivedbuilder { if (strange || fillEmptyCollisions) { strangeColl(collision.posX(), collision.posY(), collision.posZ()); strangeCents(collision.centFT0M(), collision.centFT0A(), - collision.centFT0C(), collision.centFV0A()); + centrality, collision.centFV0A()); strangeEvSels(collision.sel8()); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); @@ -487,7 +506,7 @@ struct strangederivedbuilder { } } - void processReconstructedSimulation(aod::McCollision const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) + void processReconstructedSimulation(aod::McCollision const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) { // this process function also checks if a given collision was reconstructed and checks explicitly for splitting, etc @@ -498,6 +517,10 @@ struct strangederivedbuilder { if (biggestNContribs < collision.numContrib()) { biggestNContribs = collision.numContrib(); bestCentrality = collision.centFT0C(); + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + bestCentrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); + } } } histos.fill(HIST("h2dNVerticesVsCentrality"), bestCentrality, collisions.size()); diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx index 598da25ddb1..ee2616a1fb7 100644 --- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -56,7 +56,7 @@ using std::array; using dauTracks = soa::Join; using v0Candidates = soa::Join; -using v0MCCandidates = soa::Join; +using v0MCCandidates = soa::Join; // simple checkers #define bitset(var, nbit) ((var) |= (1 << (nbit))) @@ -69,6 +69,7 @@ struct derivedlambdakzeroanalysis { Configurable analyseK0Short{"analyseK0Short", true, "process K0Short-like candidates"}; Configurable analyseLambda{"analyseLambda", true, "process Lambda-like candidates"}; Configurable analyseAntiLambda{"analyseAntiLambda", true, "process AntiLambda-like candidates"}; + Configurable calculateFeeddownMatrix{"calculateFeeddownMatrix", true, "fill feeddown matrix if MC"}; // Selection criteria: acceptance Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; @@ -93,9 +94,11 @@ struct derivedlambdakzeroanalysis { // PID (TPC) Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable doQA{"doQA", true, "do topological variable QA histograms"}; + Configurable doCompleteQA{"doCompleteQA", false, "do topological variable QA histograms"}; + Configurable doPlainQA{"doPlainQA", true, "do simple 1D QA of candidates"}; Configurable qaMinPt{"qaMinPt", 0.0f, "minimum pT for QA plots"}; - Configurable qaMaxPt{"qaMaxPt", 0.0f, "maximum pT for QA plots"}; + Configurable qaMaxPt{"qaMaxPt", 1000.0f, "maximum pT for QA plots"}; + Configurable qaCentrality{"qaCentrality", false, "qa centrality flag: check base raw values"}; // for MC Configurable doMCAssociation{"doMCAssociation", true, "if MC, do MC association"}; @@ -104,11 +107,14 @@ struct derivedlambdakzeroanalysis { Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for analysis"}; + ConfigurableAxis axisPtXi{"axisPtXi", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for feeddown from Xi"}; ConfigurableAxis axisPtCoarse{"axisPtCoarse", {VARIABLE_WIDTH, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 7.0f, 10.0f, 15.0f}, "pt axis for QA"}; ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}, "Centrality"}; + ConfigurableAxis axisRawCentrality{"axisRawCentrality", {VARIABLE_WIDTH, 0.000f, 52.320f, 75.400f, 95.719f, 115.364f, 135.211f, 155.791f, 177.504f, 200.686f, 225.641f, 252.645f, 281.906f, 313.850f, 348.302f, 385.732f, 426.307f, 470.146f, 517.555f, 568.899f, 624.177f, 684.021f, 748.734f, 818.078f, 892.577f, 973.087f, 1058.789f, 1150.915f, 1249.319f, 1354.279f, 1465.979f, 1584.790f, 1710.778f, 1844.863f, 1985.746f, 2134.643f, 2291.610f, 2456.943f, 2630.653f, 2813.959f, 3006.631f, 3207.229f, 3417.641f, 3637.318f, 3865.785f, 4104.997f, 4354.938f, 4615.786f, 4885.335f, 5166.555f, 5458.021f, 5762.584f, 6077.881f, 6406.834f, 6746.435f, 7097.958f, 7462.579f, 7839.165f, 8231.629f, 8635.640f, 9052.000f, 9484.268f, 9929.111f, 10389.350f, 10862.059f, 11352.185f, 11856.823f, 12380.371f, 12920.401f, 13476.971f, 14053.087f, 14646.190f, 15258.426f, 15890.617f, 16544.433f, 17218.024f, 17913.465f, 18631.374f, 19374.983f, 20136.700f, 20927.783f, 21746.796f, 22590.880f, 23465.734f, 24372.274f, 25314.351f, 26290.488f, 27300.899f, 28347.512f, 29436.133f, 30567.840f, 31746.818f, 32982.664f, 34276.329f, 35624.859f, 37042.588f, 38546.609f, 40139.742f, 41837.980f, 43679.429f, 45892.130f, 400000.000f}, "raw centrality signal"}; // for QA + // topological variable QA axes ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {20, 0.0f, 1.0f}, "DCA (cm)"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {20, 0.0f, 2.0f}, "DCA (cm)"}; @@ -119,6 +125,10 @@ struct derivedlambdakzeroanalysis { 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"}; + ConfigurableAxis axisITSclus{"axisITSclus", {7, 0.0f, 7.0f}, "N ITS Clusters"}; + enum species { spK0Short = 0, spLambda, spAntiLambda }; @@ -140,9 +150,12 @@ struct derivedlambdakzeroanalysis { selNegGoodTPCTrack, selPosItsOnly, selNegItsOnly, - selConsiderK0Short, // for mc tagging - selConsiderLambda, // for mc tagging - selConsiderAntiLambda // for mc tagging + selConsiderK0Short, // for mc tagging + selConsiderLambda, // for mc tagging + selConsiderAntiLambda, // for mc tagging + selPhysPrimK0Short, // for mc tagging + selPhysPrimLambda, // for mc tagging + selPhysPrimAntiLambda // for mc tagging }; uint32_t maskTopological; @@ -161,6 +174,9 @@ struct derivedlambdakzeroanalysis { uint32_t maskSelectionLambda; uint32_t maskSelectionAntiLambda; + uint32_t secondaryMaskSelectionLambda; + uint32_t secondaryMaskSelectionAntiLambda; + void init(InitContext const&) { // initialise bit masks @@ -187,9 +203,14 @@ struct derivedlambdakzeroanalysis { maskLambdaSpecific = (1 << selLambdaRapidity) | (1 << selLambdaTPC) | (1 << selLambdaCTau) | (1 << selConsiderLambda); maskAntiLambdaSpecific = (1 << selLambdaRapidity) | (1 << selAntiLambdaTPC) | (1 << selLambdaCTau) | (1 << selConsiderAntiLambda); - maskSelectionK0Short = maskTopological | maskTrackTypes | maskK0ShortSpecific; - maskSelectionLambda = maskTopological | maskTrackTypes | maskLambdaSpecific; - maskSelectionAntiLambda = maskTopological | maskTrackTypes | maskAntiLambdaSpecific; + // Primary particle selection, central to analysis + maskSelectionK0Short = maskTopological | maskTrackTypes | maskK0ShortSpecific | (1 << selPhysPrimK0Short); + maskSelectionLambda = maskTopological | maskTrackTypes | maskLambdaSpecific | (1 << selPhysPrimLambda); + maskSelectionAntiLambda = maskTopological | maskTrackTypes | maskAntiLambdaSpecific | (1 << selPhysPrimAntiLambda); + + // No primary requirement for feeddown matrix + secondaryMaskSelectionLambda = maskTopological | maskTrackTypes | maskLambdaSpecific; + secondaryMaskSelectionAntiLambda = maskTopological | maskTrackTypes | maskAntiLambdaSpecific; // Event Counters histos.add("hEventSelection", "hEventSelection", kTH1F, {{3, -0.5f, +2.5f}}); @@ -199,6 +220,14 @@ struct derivedlambdakzeroanalysis { histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); + // for QA and test purposes + auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); + + for (int ii = 1; ii < 101; ii++) { + float value = 100.5f - static_cast(ii); + hRawCentrality->SetBinContent(ii, value); + } + // histograms versus mass if (analyseK0Short) histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); @@ -207,11 +236,16 @@ struct derivedlambdakzeroanalysis { if (analyseAntiLambda) histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + if (analyseLambda && calculateFeeddownMatrix && doprocessMonteCarlo) + histos.add("h3dLambdaFeeddown", "h3dLambdaFeeddown", kTH3F, {axisCentrality, axisPt, axisPtXi}); + if (analyseAntiLambda && calculateFeeddownMatrix && doprocessMonteCarlo) + histos.add("h3dAntiLambdaFeeddown", "h3dAntiLambdaFeeddown", kTH3F, {axisCentrality, axisPt, axisPtXi}); + // demo // fast histos.add("hMassK0Short", "hMassK0Short", kTH1F, {axisK0Mass}); // QA histograms if requested - if (doQA) { + if (doCompleteQA) { // initialize for K0short... if (analyseK0Short) { histos.add("K0Short/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisDCAtoPV}); @@ -234,11 +268,50 @@ struct derivedlambdakzeroanalysis { histos.add("AntiLambda/h4dPointingAngle", "h4dPointingAngle", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPointingAngle}); histos.add("AntiLambda/h4dV0Radius", "h4dV0Radius", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisV0Radius}); } + } - // Check if doing the right thing in AP space please - histos.add("GeneralQA/h2dArmenterosAll", "h2dArmenterosAll", kTH2F, {axisAPAlpha, axisAPQt}); - histos.add("GeneralQA/h2dArmenterosSelected", "h2dArmenterosSelected", kTH2F, {axisAPAlpha, axisAPQt}); + if (doPlainQA) { + // All candidates received + histos.add("hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + + if (analyseK0Short) { + histos.add("K0Short/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0Short/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("K0Short/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("K0Short/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("K0Short/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("K0Short/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("K0Short/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + if (analyseLambda) { + histos.add("Lambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("Lambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("Lambda/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("Lambda/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("Lambda/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("Lambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("Lambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } + if (analyseAntiLambda) { + histos.add("AntiLambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("AntiLambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("AntiLambda/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("AntiLambda/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("AntiLambda/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); + histos.add("AntiLambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("AntiLambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + } } + + // Check if doing the right thing in AP space please + histos.add("GeneralQA/h2dArmenterosAll", "h2dArmenterosAll", kTH2F, {axisAPAlpha, axisAPQt}); + histos.add("GeneralQA/h2dArmenterosSelected", "h2dArmenterosSelected", kTH2F, {axisAPAlpha, axisAPQt}); } template @@ -325,14 +398,20 @@ struct derivedlambdakzeroanalysis { uint32_t bitMap = 0; // check for specific particle species - if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211 && v0.isPhysicalPrimary()) { + if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211) { bitset(bitMap, selConsiderK0Short); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimK0Short); } - if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211 && v0.isPhysicalPrimary()) { + if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211) { bitset(bitMap, selConsiderLambda); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimLambda); } - if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212 && v0.isPhysicalPrimary()) { + if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212) { bitset(bitMap, selConsiderAntiLambda); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimAntiLambda); } return bitMap; } @@ -342,70 +421,136 @@ struct derivedlambdakzeroanalysis { return (bitmap & mask) == mask; } - template - void analyseCandidate(TV0 v0, TCollision collision, uint32_t selMap) + template + void analyseCandidate(TV0 v0, float centrality, uint32_t selMap) // precalculate this information so that a check is one mask operation, not many { + auto posTrackExtra = v0.template posTrackExtra_as(); + auto negTrackExtra = v0.template negTrackExtra_as(); + + // __________________________________________ + // fill with no selection if plain QA requested + if (doPlainQA) { + histos.fill(HIST("hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("hV0Radius"), v0.v0radius()); + histos.fill(HIST("h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } + // __________________________________________ // main analysis if (verifyMask(selMap, maskSelectionK0Short) && analyseK0Short) { histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), v0.alpha(), v0.qtarm()); // cross-check - histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); + histos.fill(HIST("h3dMassK0Short"), centrality, v0.pt(), v0.mK0Short()); histos.fill(HIST("hMassK0Short"), v0.mK0Short()); + if (doPlainQA) { + histos.fill(HIST("K0Short/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("K0Short/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("K0Short/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("K0Short/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("K0Short/hV0Radius"), v0.v0radius()); + histos.fill(HIST("K0Short/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("K0Short/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } } if (verifyMask(selMap, maskSelectionLambda) && analyseLambda) { - histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); + histos.fill(HIST("h3dMassLambda"), centrality, v0.pt(), v0.mLambda()); + if (doPlainQA) { + histos.fill(HIST("Lambda/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("Lambda/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("Lambda/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("Lambda/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("Lambda/hV0Radius"), v0.v0radius()); + histos.fill(HIST("Lambda/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("Lambda/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } } if (verifyMask(selMap, maskSelectionAntiLambda) && analyseAntiLambda) { - histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); + histos.fill(HIST("h3dMassAntiLambda"), centrality, v0.pt(), v0.mAntiLambda()); + if (doPlainQA) { + histos.fill(HIST("AntiLambda/hPosDCAToPV"), v0.dcapostopv()); + histos.fill(HIST("AntiLambda/hNegDCAToPV"), v0.dcanegtopv()); + histos.fill(HIST("AntiLambda/hDCADaughters"), v0.dcaV0daughters()); + histos.fill(HIST("AntiLambda/hPointingAngle"), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("AntiLambda/hV0Radius"), v0.v0radius()); + histos.fill(HIST("AntiLambda/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); + histos.fill(HIST("AntiLambda/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + } } // __________________________________________ // do systematics / qa plots - if (doQA) { + if (doCompleteQA) { if (analyseK0Short) { if (verifyMask(selMap, maskTopoNoV0Radius | maskK0ShortSpecific)) - histos.fill(HIST("K0Short/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mK0Short(), v0.v0radius()); + histos.fill(HIST("K0Short/h4dV0Radius"), centrality, v0.pt(), v0.mK0Short(), v0.v0radius()); if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskK0ShortSpecific)) - histos.fill(HIST("K0Short/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcapostopv())); + histos.fill(HIST("K0Short/h4dPosDCAToPV"), centrality, v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcapostopv())); if (verifyMask(selMap, maskTopoNoDCANegToPV | maskK0ShortSpecific)) - histos.fill(HIST("K0Short/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcanegtopv())); + histos.fill(HIST("K0Short/h4dNegDCAToPV"), centrality, v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcanegtopv())); if (verifyMask(selMap, maskTopoNoCosPA | maskK0ShortSpecific)) - histos.fill(HIST("K0Short/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("K0Short/h4dPointingAngle"), centrality, v0.pt(), v0.mK0Short(), TMath::ACos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskK0ShortSpecific)) - histos.fill(HIST("K0Short/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mK0Short(), v0.dcaV0daughters()); + histos.fill(HIST("K0Short/h4dDCADaughters"), centrality, v0.pt(), v0.mK0Short(), v0.dcaV0daughters()); } if (analyseLambda) { if (verifyMask(selMap, maskTopoNoV0Radius | maskLambdaSpecific)) - histos.fill(HIST("Lambda/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mLambda(), v0.v0radius()); + histos.fill(HIST("Lambda/h4dV0Radius"), centrality, v0.pt(), v0.mLambda(), v0.v0radius()); if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskLambdaSpecific)) - histos.fill(HIST("Lambda/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::Abs(v0.dcapostopv())); + histos.fill(HIST("Lambda/h4dPosDCAToPV"), centrality, v0.pt(), v0.mLambda(), TMath::Abs(v0.dcapostopv())); if (verifyMask(selMap, maskTopoNoDCANegToPV | maskLambdaSpecific)) - histos.fill(HIST("Lambda/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::Abs(v0.dcanegtopv())); + histos.fill(HIST("Lambda/h4dNegDCAToPV"), centrality, v0.pt(), v0.mLambda(), TMath::Abs(v0.dcanegtopv())); if (verifyMask(selMap, maskTopoNoCosPA | maskLambdaSpecific)) - histos.fill(HIST("Lambda/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("Lambda/h4dPointingAngle"), centrality, v0.pt(), v0.mLambda(), TMath::ACos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskLambdaSpecific)) - histos.fill(HIST("Lambda/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mLambda(), v0.dcaV0daughters()); + histos.fill(HIST("Lambda/h4dDCADaughters"), centrality, v0.pt(), v0.mLambda(), v0.dcaV0daughters()); } if (analyseAntiLambda) { if (verifyMask(selMap, maskTopoNoV0Radius | maskAntiLambdaSpecific)) - histos.fill(HIST("AntiLambda/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), v0.v0radius()); + histos.fill(HIST("AntiLambda/h4dV0Radius"), centrality, v0.pt(), v0.mAntiLambda(), v0.v0radius()); if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskAntiLambdaSpecific)) - histos.fill(HIST("AntiLambda/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcapostopv())); + histos.fill(HIST("AntiLambda/h4dPosDCAToPV"), centrality, v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcapostopv())); if (verifyMask(selMap, maskTopoNoDCANegToPV | maskAntiLambdaSpecific)) - histos.fill(HIST("AntiLambda/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcanegtopv())); + histos.fill(HIST("AntiLambda/h4dNegDCAToPV"), centrality, v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcanegtopv())); if (verifyMask(selMap, maskTopoNoCosPA | maskAntiLambdaSpecific)) - histos.fill(HIST("AntiLambda/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("AntiLambda/h4dPointingAngle"), centrality, v0.pt(), v0.mAntiLambda(), TMath::ACos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskAntiLambdaSpecific)) - histos.fill(HIST("AntiLambda/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), v0.dcaV0daughters()); + histos.fill(HIST("AntiLambda/h4dDCADaughters"), centrality, v0.pt(), v0.mAntiLambda(), v0.dcaV0daughters()); } } // end systematics / qa } + template + void fillFeeddownMatrix(TV0 v0, float centrality, uint32_t selMap) + // fill feeddown matrix for Lambdas or AntiLambdas + // fixme: a potential improvement would be to consider mass windows for the l/al + { + if (!v0.has_motherMCPart()) + return; // does not have mother particle in record, skip + + auto v0mother = v0.motherMCPart(); + float rapidityXi = RecoDecay::y(std::array{v0mother.px(), v0mother.py(), v0mother.pz()}, o2::constants::physics::MassXiMinus); + if (fabs(rapidityXi) > 0.5f) + return; // not a valid mother rapidity (PDG selection is later) + + // __________________________________________ + if (verifyMask(selMap, secondaryMaskSelectionLambda) && analyseLambda) { + if (v0mother.pdgCode() == 3312 && v0mother.isPhysicalPrimary()) + histos.fill(HIST("h3dLambdaFeeddown"), centrality, v0.pt(), std::hypot(v0mother.px(), v0mother.py())); + } + if (verifyMask(selMap, secondaryMaskSelectionAntiLambda) && analyseAntiLambda) { + if (v0mother.pdgCode() == -3312 && v0mother.isPhysicalPrimary()) + histos.fill(HIST("h3dAntiLambdaFeeddown"), centrality, v0.pt(), std::hypot(v0mother.px(), v0mother.py())); + } + } + // ______________________________________________________ // Real data processing - no MC subscription - void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) + void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) { histos.fill(HIST("hEventSelection"), 0. /* all collisions */); if (!collision.sel8()) { @@ -417,7 +562,14 @@ struct derivedlambdakzeroanalysis { return; } histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); - histos.fill(HIST("hEventCentrality"), collision.centFT0C()); + + float centrality = collision.centFT0C(); + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); + } + + histos.fill(HIST("hEventCentrality"), centrality); // __________________________________________ // perform main analysis @@ -432,14 +584,15 @@ struct derivedlambdakzeroanalysis { // consider for histograms for all species selMap = selMap | (1 << selConsiderK0Short) | (1 << selConsiderLambda) | (1 << selConsiderAntiLambda); + selMap = selMap | (1 << selPhysPrimK0Short) | (1 << selPhysPrimLambda) | (1 << selPhysPrimAntiLambda); - analyseCandidate(v0, collision, selMap); + analyseCandidate(v0, centrality, selMap); } // end v0 loop } // ______________________________________________________ // Simulated processing (subscribes to MC information too) - void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&) + void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&) { histos.fill(HIST("hEventSelection"), 0. /* all collisions */); if (!collision.sel8()) { @@ -451,7 +604,14 @@ struct derivedlambdakzeroanalysis { return; } histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); - histos.fill(HIST("hEventCentrality"), collision.centFT0C()); + + float centrality = collision.centFT0C(); + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); + } + + histos.fill(HIST("hEventCentrality"), centrality); // __________________________________________ // perform main analysis @@ -463,15 +623,19 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("GeneralQA/h2dArmenterosAll"), v0.alpha(), v0.qtarm()); uint32_t selMap = computeReconstructionBitmap(v0, collision); + selMap = selMap | computeMCAssociation(v0); + + // feeddown matrix always with association + if (calculateFeeddownMatrix) + fillFeeddownMatrix(v0, centrality, selMap); - // consider only associated candidates if asked to do so - if (doMCAssociation) { - selMap = selMap | computeMCAssociation(v0); - } else { + // consider only associated candidates if asked to do so, disregard association + if (!doMCAssociation) { selMap = selMap | (1 << selConsiderK0Short) | (1 << selConsiderLambda) | (1 << selConsiderAntiLambda); + selMap = selMap | (1 << selPhysPrimK0Short) | (1 << selPhysPrimLambda) | (1 << selPhysPrimAntiLambda); } - analyseCandidate(v0, collision, selMap); + analyseCandidate(v0, centrality, selMap); } // end v0 loop }