|
| 1 | +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. |
| 2 | +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 3 | +// All rights not expressly granted are reserved. |
| 4 | +// |
| 5 | +// This software is distributed under the terms of the GNU General Public |
| 6 | +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 7 | +// |
| 8 | +// In applying this license CERN does not waive the privileges and immunities |
| 9 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 10 | +// or submit itself to any jurisdiction. |
| 11 | + |
| 12 | +/// \file femtoDreamDebugReso.cxx |
| 13 | +/// \brief Tasks that reads the particle tables and fills QA histograms for V0s |
| 14 | +/// \author Christopher Klumm, TU München, christopher.klumm@cern.ch |
| 15 | + |
| 16 | +#include "PWGCF/DataModel/FemtoDerived.h" |
| 17 | +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" |
| 18 | +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" |
| 19 | + |
| 20 | +#include "DataFormatsParameters/GRPObject.h" |
| 21 | +#include "Framework/ASoAHelpers.h" |
| 22 | +#include "Framework/AnalysisTask.h" |
| 23 | +#include "Framework/HistogramRegistry.h" |
| 24 | +#include "Framework/RunningWorkflowInfo.h" |
| 25 | +#include "Framework/StepTHn.h" |
| 26 | +#include "Framework/runDataProcessing.h" |
| 27 | + |
| 28 | +#include "TVector3.h" |
| 29 | + |
| 30 | +#include "fairlogger/Logger.h" |
| 31 | + |
| 32 | +#include <cstdint> |
| 33 | +#include <string> |
| 34 | +#include <vector> |
| 35 | + |
| 36 | +using namespace o2; |
| 37 | +using namespace o2::analysis::femtoDream; |
| 38 | +using namespace o2::framework; |
| 39 | +using namespace o2::framework::expressions; |
| 40 | +using namespace o2::soa; |
| 41 | + |
| 42 | +struct FemtoDreamDebugReso { |
| 43 | + SliceCache cache; |
| 44 | + |
| 45 | + struct : ConfigurableGroup { |
| 46 | + std::string prefix = std::string("resonance"); |
| 47 | + |
| 48 | + Configurable<int> confResoPDGCode{"confResoPDGCode", 333, "Reso - PDG code"}; |
| 49 | + Configurable<int> confResoChildPosPDGCode{"confResoChildPosPDGCode", 321, "Positive Child - PDG code"}; |
| 50 | + Configurable<int> confResoChildNegPDGCode{"confResoChildNegPDGCode", 321, "Negative Child- PDG code"}; |
| 51 | + |
| 52 | + ConfigurableAxis confResoTempFitVarBins{"confResoTempFitVarBins", {300, 0.95, 1.}, "Reso: binning of the TempFitVar in the pT vs. TempFitVar plot"}; |
| 53 | + ConfigurableAxis confResoTempFitVarMomentumBins{"confResoTempFitVarMomentumBins", {20, 0.5, 4.05}, "Reso: pT binning of the pT vs. TempFitVar plot"}; |
| 54 | + ConfigurableAxis confBinmult{"confBinmult", {1, 0, 1}, "multiplicity Binning"}; |
| 55 | + ConfigurableAxis confDummy{"confDummy", {1, 0, 1}, "Dummy axis for inv mass"}; |
| 56 | + |
| 57 | + Configurable<int> confResoTempFitVarMomentum{"confResoTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; |
| 58 | + ConfigurableAxis confResoInvMassBins{"confResoInvMassBins", {200, 1, 1.2}, "Reso: InvMass binning"}; |
| 59 | + |
| 60 | + ConfigurableAxis confResoChildTempFitVarMomentumBins{"confResoChildTempFitVarMomentumBins", {600, 0, 6}, "p binning for the p vs Nsigma TPC/TOF plot"}; |
| 61 | + ConfigurableAxis confResoChildNsigmaTPCBins{"confResoChildNsigmaTPCBins", {1600, -8, 8}, "binning of Nsigma TPC plot"}; // TPC and TOf seperate doen't make sense really right?? |
| 62 | + ConfigurableAxis confResoChildNsigmaTOFBins{"confResoChildNsigmaTOFBins", {3000, -15, 15}, "binning of the Nsigma TOF plot"}; |
| 63 | + ConfigurableAxis confResoChildNsigmaTPCTOFBins{"confResoChildNsigmaTPCTOFBins", {1000, 0, 10}, "binning of the Nsigma TPC+TOF plot"}; |
| 64 | + ConfigurableAxis confResoChildNsigmaITSBins{"confResoChildNsigmaITSBins", {600, -3, 3}, "binning of the Nsigma ITS plot"}; |
| 65 | + |
| 66 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildPosCutBit{"confResoChildPosCutBit", 4860458, "Positive Child of Reso - Selection bit from cutCulator"}; |
| 67 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildPosTPCBit{"confResoChildPosTPCBit", 64, "Positive Child of Reso - PID bit from cutCulator"}; |
| 68 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildPosTPCTOFBit{"confResoChildPosTPCTOFBit", 32, "Positive Child of Reso - PID bit from cutCulator"}; |
| 69 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildNegCutBit{"confResoChildNegCutBit", 4860457, "Negative Child of Reso - PID bit from cutCulator"}; |
| 70 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildNegMergedTPCBit{"confResoChildNegMergedTPCBit", 258, "Negative Child of Reso - PID bit from cutCulator"}; // change |
| 71 | + Configurable<aod::femtodreamparticle::cutContainerType> confResoChildNegMergedTPCTOFBit{"confResoChildNegMergedTPCTOFBit", 130, "Negative Child of Reso - PID bit from cutCulator"}; // change |
| 72 | + ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; |
| 73 | + ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; |
| 74 | + } resonance; |
| 75 | + |
| 76 | + using FemtoFullParticles = soa::Join<aod::FDParticles, aod::FDExtParticles>; |
| 77 | + |
| 78 | + Partition<FemtoFullParticles> partsTwo = (ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kResoPosdaughTPC_NegdaughTPC), ncheckbit(aod::femtodreamparticle::pidcut, resonance.confResoChildPosTPCBit) && ncheckbit(aod::femtodreamparticle::cut, resonance.confResoChildNegMergedTPCBit), false) || |
| 79 | + ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kResoPosdaughTOF_NegdaughTOF), ncheckbit(aod::femtodreamparticle::pidcut, resonance.confResoChildPosTPCTOFBit) && ncheckbit(aod::femtodreamparticle::cut, resonance.confResoChildNegMergedTPCTOFBit), false) || |
| 80 | + ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kResoPosdaughTOF_NegdaughTPC), ncheckbit(aod::femtodreamparticle::pidcut, resonance.confResoChildPosTPCTOFBit) && ncheckbit(aod::femtodreamparticle::cut, resonance.confResoChildNegMergedTPCBit), false) || |
| 81 | + ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kResoPosdaughTPC_NegdaughTOF), ncheckbit(aod::femtodreamparticle::pidcut, resonance.confResoChildPosTPCBit) && ncheckbit(aod::femtodreamparticle::cut, resonance.confResoChildNegMergedTPCTOFBit), false)); |
| 82 | + |
| 83 | + Preslice<FemtoFullParticles> perCol = aod::femtodreamparticle::fdCollisionId; |
| 84 | + |
| 85 | + /// Histogramming |
| 86 | + FemtoDreamEventHisto eventHisto; |
| 87 | + FemtoDreamParticleHisto<aod::femtodreamparticle::ParticleType::kResoChild, 3> posResoChildHistos; |
| 88 | + FemtoDreamParticleHisto<aod::femtodreamparticle::ParticleType::kResoChild, 4> negResoChildHistos; |
| 89 | + FemtoDreamParticleHisto<aod::femtodreamparticle::ParticleType::kReso> resoHistos; |
| 90 | + |
| 91 | + /// Histogram output |
| 92 | + HistogramRegistry eventRegistry{"Event", {}, OutputObjHandlingPolicy::AnalysisObject}; |
| 93 | + HistogramRegistry resoRegistry{"FullResoQA", {}, OutputObjHandlingPolicy::AnalysisObject}; |
| 94 | + |
| 95 | + void init(InitContext&) |
| 96 | + { |
| 97 | + posResoChildHistos.init(&resoRegistry, resonance.confBinmult, resonance.confDummy, resonance.confResoChildTempFitVarMomentumBins, resonance.confDummy, resonance.confDummy, resonance.confChildTempFitVarBins, resonance.confResoChildNsigmaTPCBins, resonance.confResoChildNsigmaTOFBins, resonance.confResoChildNsigmaTPCTOFBins, resonance.confResoChildNsigmaITSBins, resonance.confResoInvMassBins, resonance.confDummy, false, resonance.confResoChildPosPDGCode.value, true); // isDebug == TRUE |
| 98 | + negResoChildHistos.init(&resoRegistry, resonance.confBinmult, resonance.confDummy, resonance.confResoChildTempFitVarMomentumBins, resonance.confDummy, resonance.confDummy, resonance.confChildTempFitVarBins, resonance.confResoChildNsigmaTPCBins, resonance.confResoChildNsigmaTOFBins, resonance.confResoChildNsigmaTPCTOFBins, resonance.confResoChildNsigmaITSBins, resonance.confResoInvMassBins, resonance.confDummy, false, resonance.confResoChildNegPDGCode, true); // isDebug == TRUE |
| 99 | + resoHistos.init(&resoRegistry, resonance.confBinmult, resonance.confDummy, resonance.confResoTempFitVarMomentumBins, resonance.confDummy, resonance.confDummy, resonance.confResoTempFitVarBins, resonance.confResoChildNsigmaTPCBins, resonance.confResoChildNsigmaTOFBins, resonance.confResoChildNsigmaTPCTOFBins, resonance.confResoChildNsigmaITSBins, resonance.confResoInvMassBins, resonance.confDummy, false, resonance.confResoPDGCode.value, true); // isDebug == TRUE, isMc ==FALSE for all |
| 100 | + resoRegistry.add("hArmenterosPodolanski/hArmenterosPodolanskiPlot", "; #alpha; p_{T} (MeV/#it{c})", kTH2F, {{100, -1, 1}, {500, -0.3, 2}}); |
| 101 | + } |
| 102 | + |
| 103 | + /// Porduce QA plots for V0 & Reso selection in FemtoDream framework |
| 104 | + void process(o2::aod::FDCollision const& col, FemtoFullParticles const& parts) |
| 105 | + { |
| 106 | + |
| 107 | + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); // maybe . instead of -> ?? |
| 108 | + for (const auto& part : groupPartsTwo) { |
| 109 | + if (!part.has_children()) { |
| 110 | + LOG(warn) << " Reso has no children"; |
| 111 | + continue; |
| 112 | + } |
| 113 | + |
| 114 | + const auto& posresoChild = parts.iteratorAt(part.index() - 2); |
| 115 | + const auto& negresoChild = parts.iteratorAt(part.index() - 1); |
| 116 | + if (posresoChild.globalIndex() != part.childrenIds()[0] || negresoChild.globalIndex() != part.childrenIds()[1]) { |
| 117 | + continue; |
| 118 | + } |
| 119 | + if (posresoChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kResoChild) && |
| 120 | + (posresoChild.cut() & resonance.confResoChildPosCutBit) == resonance.confResoChildPosCutBit && |
| 121 | + negresoChild.partType() == uint8_t(aod::femtodreamparticle::ParticleType::kResoChild) && |
| 122 | + (negresoChild.cut() & resonance.confResoChildNegCutBit) == resonance.confResoChildNegCutBit) { |
| 123 | + |
| 124 | + TVector3 pparent(part.px(), part.py(), part.pz()); // Parent momentum (px, py, pz) |
| 125 | + TVector3 pplus(posresoChild.px(), posresoChild.py(), posresoChild.pz()); // Daughter 1 momentum (px, py, pz) |
| 126 | + TVector3 pminus(negresoChild.px(), negresoChild.py(), negresoChild.pz()); // Daughter 2 momentum (px, py, pz) |
| 127 | + |
| 128 | + double pLplus = pplus.Dot(pparent) / pparent.Mag(); |
| 129 | + double pLminus = pminus.Dot(pparent) / pparent.Mag(); |
| 130 | + float alpha = (pLplus - pLminus) / (pLplus + pLminus); |
| 131 | + |
| 132 | + TVector3 pperp = pplus - (pparent * (pLplus / pparent.Mag())); |
| 133 | + double qtarm = pperp.Mag(); |
| 134 | + |
| 135 | + resoRegistry.fill(HIST("hArmenterosPodolanski/hArmenterosPodolanskiPlot"), alpha, qtarm); |
| 136 | + |
| 137 | + resoHistos.fillQA<false, true>(part, static_cast<aod::femtodreamparticle::MomentumType>(resonance.confResoTempFitVarMomentum.value), col.multNtr(), col.multV0M()); |
| 138 | + posResoChildHistos.fillQA<false, true>(posresoChild, static_cast<aod::femtodreamparticle::MomentumType>(resonance.confResoTempFitVarMomentum.value), col.multNtr(), col.multV0M()); |
| 139 | + negResoChildHistos.fillQA<false, true>(negresoChild, static_cast<aod::femtodreamparticle::MomentumType>(resonance.confResoTempFitVarMomentum.value), col.multNtr(), col.multV0M()); |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | +}; |
| 144 | + |
| 145 | +WorkflowSpec |
| 146 | + defineDataProcessing(ConfigContext const& cfgc) |
| 147 | +{ |
| 148 | + WorkflowSpec workflow{ |
| 149 | + adaptAnalysisTask<FemtoDreamDebugReso>(cfgc), |
| 150 | + }; |
| 151 | + return workflow; |
| 152 | +} |
0 commit comments