|
| 1 | +// Copyright 2019-2020 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 | +#include "PWGLF/DataModel/LFSlimHeLambda.h" |
| 13 | + |
| 14 | +#include <Framework/ASoAHelpers.h> |
| 15 | +#include <Framework/AnalysisTask.h> |
| 16 | +#include <Framework/HistogramRegistry.h> |
| 17 | +#include <Framework/runDataProcessing.h> |
| 18 | + |
| 19 | +#include <Math/Vector4D.h> |
| 20 | + |
| 21 | +#include <memory> |
| 22 | + |
| 23 | +namespace |
| 24 | +{ |
| 25 | +std::shared_ptr<TH2> hInvariantMassUS[2]; |
| 26 | +std::shared_ptr<TH2> hInvariantMassLS[2]; |
| 27 | +std::shared_ptr<TH2> hRotationInvariantMassUS[2]; |
| 28 | +std::shared_ptr<TH2> hRotationInvariantMassLS[2]; |
| 29 | +std::shared_ptr<TH2> hRotationInvariantMassAntiLSeta[2]; |
| 30 | +std::shared_ptr<TH2> hInvariantMassLambda[2]; |
| 31 | +std::shared_ptr<TH2> hCosPALambda; |
| 32 | +std::shared_ptr<TH2> hNsigmaHe3; |
| 33 | +std::shared_ptr<TH2> hNsigmaProton; |
| 34 | +}; // namespace |
| 35 | + |
| 36 | +using namespace o2; |
| 37 | +using namespace o2::framework; |
| 38 | +using namespace o2::framework::expressions; |
| 39 | +using namespace o2::constants::physics; |
| 40 | + |
| 41 | +struct he3LambdaDerivedAnalysis { |
| 42 | + HistogramRegistry mRegistry{"He3LambdaDerivedAnalysis"}; |
| 43 | + |
| 44 | + Configurable<int> cfgNrotations{"cfgNrotations", 7, "Number of rotations for He3 candidates"}; |
| 45 | + Configurable<bool> cfgMirrorEta{"cfgMirrorEta", true, "Mirror eta for He3 candidates"}; |
| 46 | + Configurable<float> cfgMinCosPA{"cfgMinCosPA", 0.99, "Minimum cosPA for Lambda candidates"}; |
| 47 | + Configurable<float> cfgMaxNSigmaTPCHe3{"cfgMaxNSigmaTPCHe3", 2.0, "Maximum nSigmaTPC for He3 candidates"}; |
| 48 | + Configurable<float> cfgMinLambdaPt{"cfgMinLambdaPt", 0.4, "Minimum pT for Lambda candidates"}; |
| 49 | + Configurable<float> cfgMaxLambdaDeltaM{"cfgMaxLambdaDeltaM", 10.0e-3, "Maximum deltaM for Lambda candidates"}; |
| 50 | + |
| 51 | + void init(InitContext const&) |
| 52 | + { |
| 53 | + constexpr double ConstituentsMass = o2::constants::physics::MassProton + o2::constants::physics::MassNeutron * 2 + o2::constants::physics::MassSigmaPlus; |
| 54 | + for (int i = 0; i < 2; ++i) { |
| 55 | + hInvariantMassUS[i] = mRegistry.add<TH2>(Form("hInvariantMassUS%i", i), "Invariant Mass", {HistType::kTH2D, {{45, 1., 10}, {100, ConstituentsMass - 0.05, ConstituentsMass + 0.05}}}); |
| 56 | + hInvariantMassLS[i] = mRegistry.add<TH2>(Form("hInvariantMassLS%i", i), "Invariant Mass", {HistType::kTH2D, {{45, 1., 10}, {100, ConstituentsMass - 0.05, ConstituentsMass + 0.05}}}); |
| 57 | + hRotationInvariantMassUS[i] = mRegistry.add<TH2>(Form("hRotationInvariantMassUS%i", i), "Rotation Invariant Mass", {HistType::kTH2D, {{45, 1., 10}, {100, ConstituentsMass - 0.05, ConstituentsMass + 0.05}}}); |
| 58 | + hRotationInvariantMassLS[i] = mRegistry.add<TH2>(Form("hRotationInvariantMassLS%i", i), "Rotation Invariant Mass", {HistType::kTH2D, {{45, 1., 10}, {100, ConstituentsMass - 0.05, ConstituentsMass + 0.05}}}); |
| 59 | + hInvariantMassLambda[i] = mRegistry.add<TH2>(Form("hInvariantMassLambda%i", i), "Invariant Mass Lambda", {HistType::kTH2D, {{50, 0., 10.}, {30, o2::constants::physics::MassLambda0 - 0.015, o2::constants::physics::MassLambda0 + 0.015}}}); |
| 60 | + hRotationInvariantMassAntiLSeta[i] = mRegistry.add<TH2>(Form("hRotationInvariantMassAntiLSeta%i", i), "Rotation Invariant Mass Anti-Lambda", {HistType::kTH2D, {{45, 1., 10}, {100, ConstituentsMass - 0.05, ConstituentsMass + 0.05}}}); |
| 61 | + } |
| 62 | + hCosPALambda = mRegistry.add<TH2>("hCosPALambda", "Cosine of Pointing Angle for Lambda", {HistType::kTH2D, {{50, 0., 10.}, {500, 0.9, 1.}}}); |
| 63 | + hNsigmaHe3 = mRegistry.add<TH2>("hNsigmaHe3", "nSigma TPC for He3", {HistType::kTH2D, {{100, -10., 10.}, {200, -5, 5.}}}); |
| 64 | + hNsigmaProton = mRegistry.add<TH2>("hNsigmaProton", "nSigma TPC for Proton", {HistType::kTH2D, {{100, -10., 10.}, {200, -5, 5.}}}); |
| 65 | + } |
| 66 | + |
| 67 | + void processSameEvent(o2::aod::LFEvents::iterator const& collision, o2::aod::LFHe3 const& he3s, o2::aod::LFLambda const& lambdas) |
| 68 | + { |
| 69 | + std::vector<he3Candidate> he3Candidates; |
| 70 | + he3Candidates.reserve(he3s.size()); |
| 71 | + std::vector<lambdaCandidate> lambdaCandidates; |
| 72 | + lambdaCandidates.reserve(lambdas.size()); |
| 73 | + for (const auto& he3 : he3s) { |
| 74 | + if (he3.lfEventId() != collision.globalIndex()) { |
| 75 | + std::cout << "He3 candidate does not match event index, skipping." << std::endl; |
| 76 | + return; |
| 77 | + } |
| 78 | + he3Candidate candidate; |
| 79 | + candidate.momentum = ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double>>(he3.pt(), he3.eta(), he3.phi(), o2::constants::physics::MassHelium3); |
| 80 | + candidate.nSigmaTPC = he3.nSigmaTPC(); |
| 81 | + candidate.dcaXY = he3.dcaXY(); |
| 82 | + candidate.dcaZ = he3.dcaZ(); |
| 83 | + candidate.tpcNClsFound = he3.tpcNCls(); |
| 84 | + candidate.itsNCls = he3.itsClusterSizes(); |
| 85 | + candidate.itsClusterSizes = he3.itsClusterSizes(); |
| 86 | + candidate.sign = he3.sign(); |
| 87 | + hNsigmaHe3->Fill(he3.pt() * he3.sign(), he3.nSigmaTPC()); |
| 88 | + if (std::abs(he3.nSigmaTPC()) > cfgMaxNSigmaTPCHe3) { |
| 89 | + continue; // Skip candidates with nSigmaTPC outside range |
| 90 | + } |
| 91 | + he3Candidates.push_back(candidate); |
| 92 | + } |
| 93 | + for (const auto& lambda : lambdas) { |
| 94 | + if (lambda.lfEventId() != collision.globalIndex()) { |
| 95 | + std::cout << "Lambda candidate does not match event index, skipping." << std::endl; |
| 96 | + return; |
| 97 | + } |
| 98 | + lambdaCandidate candidate; |
| 99 | + candidate.momentum.SetCoordinates(lambda.pt(), lambda.eta(), lambda.phi(), o2::constants::physics::MassLambda0); |
| 100 | + candidate.mass = lambda.mass(); |
| 101 | + candidate.cosPA = lambda.cosPA(); |
| 102 | + candidate.dcaV0Daughters = lambda.dcaDaughters(); |
| 103 | + hCosPALambda->Fill(lambda.pt(), candidate.cosPA); |
| 104 | + // hNsigmaProton->Fill(lambda.pt() * lambda.sign(), lambda.protonNSigmaTPC()); |
| 105 | + hInvariantMassLambda[0]->Fill(lambda.pt(), lambda.mass()); |
| 106 | + if (candidate.cosPA < cfgMinCosPA || lambda.pt() < cfgMinLambdaPt || |
| 107 | + std::abs(lambda.mass() - o2::constants::physics::MassLambda0) > cfgMaxLambdaDeltaM) { |
| 108 | + continue; // Skip candidates with low cosPA |
| 109 | + } |
| 110 | + hInvariantMassLambda[1]->Fill(lambda.pt(), lambda.mass()); |
| 111 | + lambdaCandidates.push_back(candidate); |
| 112 | + } |
| 113 | + |
| 114 | + for (const auto& he3 : he3Candidates) { |
| 115 | + for (const auto& lambda : lambdaCandidates) { |
| 116 | + auto pairMomentum = lambda.momentum + he3.momentum; // Calculate invariant mass |
| 117 | + (he3.sign * lambda.sign > 0 ? hInvariantMassLS : hInvariantMassUS)[he3.sign > 0]->Fill(pairMomentum.Pt(), pairMomentum.M()); |
| 118 | + } |
| 119 | + for (int iEta{0}; iEta <= cfgMirrorEta; ++iEta) { |
| 120 | + for (int iR{0}; iR <= cfgNrotations; ++iR) { |
| 121 | + auto he3Momentum = ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double>>(he3.momentum.Pt(), (1. - iEta * 2.) * he3.momentum.Eta(), he3.momentum.Phi() + TMath::Pi() * (0.75 + 0.5 * iR / cfgNrotations), he3.momentum.M()); |
| 122 | + for (const auto& lambda : lambdaCandidates) { |
| 123 | + auto pairMomentum = lambda.momentum + he3Momentum; // Calculate invariant mass |
| 124 | + (he3.sign * lambda.sign > 0 ? hRotationInvariantMassLS : hRotationInvariantMassUS)[he3.sign > 0]->Fill(pairMomentum.Pt(), pairMomentum.M()); |
| 125 | + if (he3.sign < 0 && lambda.sign < 0) { |
| 126 | + hRotationInvariantMassAntiLSeta[iEta]->Fill(pairMomentum.Pt(), pairMomentum.M()); |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + } |
| 131 | + } |
| 132 | + } |
| 133 | + PROCESS_SWITCH(he3LambdaDerivedAnalysis, processSameEvent, "Process same event", true); |
| 134 | +}; |
| 135 | + |
| 136 | +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) |
| 137 | +{ |
| 138 | + return WorkflowSpec{ |
| 139 | + adaptAnalysisTask<he3LambdaDerivedAnalysis>(cfgc)}; |
| 140 | +} |
0 commit comments