Skip to content

Commit 98bf92c

Browse files
committed
First version of polarization code, with traditional ROOT vectors (INCOMPLETE CODE, just bookkeeping!)
1 parent 5692752 commit 98bf92c

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
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+
/// \file lambdaJetPolarizationIonsDerived.cxx
13+
/// \brief Lambda and antiLambda polarization analysis task using derived data
14+
///
15+
/// \author Cicero Domenico Muncinelli <cicero.domenico.muncinelli@cern.ch>, Campinas State University
16+
//
17+
// Jet Polarization Ions task -- Derived data
18+
// ================
19+
//
20+
// This code loops over custom derived data tables defined on
21+
// lambdaJetPolarizationIons.h (JetsRing, LambdaLikeV0sRing).
22+
// From this derived data, calculates polarization on an EbE
23+
// basis.
24+
//
25+
//
26+
// Comments, questions, complaints, suggestions?
27+
// Please write to:
28+
// cicero.domenico.muncinelli@cern.ch
29+
//
30+
31+
#include <Framework/ASoA.h>
32+
#include <Framework/ASoAHelpers.h>
33+
#include <Framework/AnalysisDataModel.h>
34+
#include <Framework/AnalysisTask.h>
35+
#include <Framework/Logger.h>
36+
#include <Framework/runDataProcessing.h>
37+
38+
// Custom data model:
39+
#include "PWGLF/DataModel/lambdaJetPolarizationIons.h"
40+
41+
#include <cmath>
42+
#include <map>
43+
#include <string>
44+
#include <vector>
45+
46+
// #include <TLorentzVector.h>
47+
// #include <TVector3.h>
48+
// New recommended format:
49+
#include <Math/Vector3D.h>
50+
#include <Math/Vector4D.h>
51+
52+
using namespace o2;
53+
using namespace o2::framework;
54+
using namespace o2::framework::expressions;
55+
using namespace ROOT::Math;
56+
// using namespace o2::aod::lambdajetpol; // Used it explicitly along the code for clarity
57+
struct lambdaJetPolarizationIonsDerived {
58+
const double protonMass = o2::constants::physics::MassProton; // Assumes particle identification for daughter is perfect
59+
const double lambdaWeakDecayConstant = 0.747; // Fixed as a constant for this analysis.
60+
61+
62+
63+
64+
65+
66+
void processPolarizationData(aod::RingCollisions const& collisions, aod::RingJets const& jets, aod::RingLambdaLikeV0s const& v0s){
67+
68+
for (auto const& collision : collisions) {
69+
const auto collId = collision.collIdx();
70+
const double centrality = collision.centrality();
71+
72+
// Slice jets and V0s belonging to this collision
73+
auto jetsInColl = jets.sliceBy(o2::aod::lambdajetpol::collIdx, collId);
74+
auto v0sInColl = v0s.sliceBy(o2::aod::lambdajetpol::collIdx, collId);
75+
76+
// Check if there is at least one V0 and one jet in the collision:
77+
// (in the way I fill the table, there is always at least one V0 in
78+
// the stored collision, but the jets table can not be filled for
79+
// that collision, and a collision may not be filled when the jets
80+
// table is. Be mindful of that!)
81+
if (jetsInColl.empty() || v0sInColl.empty()) continue;
82+
83+
// Get leading jet:
84+
double leadingJetPt = -1;
85+
o2::aod::RingJets::iterator leadingJet;
86+
for (auto const& jet : jetsInColl) {
87+
const auto jetpt = jet.jetPt();
88+
if (jetpt > leadingJetPt){
89+
leadingJetPt = jetpt;
90+
leadingJet = jet;
91+
}
92+
}
93+
94+
// Now you can use:
95+
const double leadingJetEta = leadingJet.jetEta();
96+
const double leadingJetPhi = leadingJet.jetPhi();
97+
98+
// Convert to 3-vector components for inner product:
99+
const double jetPx = leadingJetPt * std::cos(leadingJetPhi);
100+
const double jetPy = leadingJetPt * std::sin(leadingJetPhi);
101+
const double jetPz = leadingJetPt * std::sinh(leadingJetEta);
102+
103+
// TODO: add centrality selection procedure and options (one configurable for no centrality separation at all too!)
104+
// TODO: add Lambda candidate selection. Think of a statistical method like signal extraction (if possible) for ring polarization
105+
// TODO: add calculations with second to leading jet too.
106+
// TODO: Add calculations with leading particle
107+
for (auto const& v0 : v0sInColl) {
108+
const double v0pt = v0.V0Pt();
109+
const double v0eta = v0.v0Eta();
110+
const double v0phi = v0.Phi();
111+
112+
double v0LambdaMass;
113+
double protonLikePt;
114+
double protonLikeEta;
115+
double protonLikePhi;
116+
if (isLambda){
117+
v0LambdaMass = v0.MassLambda();
118+
protonLikePt = v0.PosPt();
119+
protonLikeEta = v0.PosEta();
120+
protonLikePhi = v0.PosPhi();
121+
}
122+
// (TODO: implement AntiLambda polarization)
123+
// if (isAntiLambda){
124+
// }
125+
126+
const double lambdaPx = v0pt * std::cos(v0phi);
127+
const double lambdaPy = v0pt * std::sin(v0phi);
128+
const double lambdaPz = v0pt * std::sinh(v0eta);
129+
const double lambdaMomentumSquared = lambdaPx*lambdaPx + lambdaPy*lambdaPy + lambdaPz*lambdaPz;
130+
const double lambdaE = std::sqrt(v0LambdaMass*v0LambdaMass + lambdaMomentumSquared);
131+
// const double lambdaRapidity = 0.5 * std::log((lambdaE + lambdaPz) / (lambdaE - lambdaPz)); // For extra selection criteria later
132+
const double lambdaRapidity = std::atanh(lambdaPz / lambdaE); // More numerically stable
133+
134+
const double protonPx = protonLikePt * std::cos(protonLikePhi);
135+
const double protonPy = protonLikePt * std::sin(protonLikePhi);
136+
const double protonPz = protonLikePt * std::sinh(protonLikeEta);
137+
const double protonMomentumSquared = protonPx*protonPx + protonPy*protonPy + protonPz*protonPz;
138+
const double protonE = std::sqrt(protonMass*protonMass + protonMomentumSquared);
139+
140+
TLorentzVector lambdaLike4Vec(lambdaPx, lambdaPy, lambdaPz, lambdaE);
141+
TLorentzVector protonLike4Vec(protonPx, protonPy, protonPz, protonE);
142+
143+
// Boosting proton into lambda frame:
144+
TVector3 betaInverse = -lambdaLike4Vec.BoostVector(); // Boost trivector that goes from laboratory frame to the rest frame
145+
TLorentzVector protonLike4VecStar = protonLike4Vec;
146+
protonLike4VecStar.Boost(betaInverse);
147+
148+
TVector3 protonLikeStarUnitVec = (protonLike4VecStar.Vect()).Unit();
149+
TVector3 jetUnitVec = (TVector3(jetPx, jetPy, jetPz)).Unit();
150+
TVector3 lambda3Vec = TVector3(lambdaPx, lambdaPy, lambdaPz);
151+
152+
// Calculating inner product:
153+
double crossX = jetUnitVec.Y()*lambdaPz - jetUnitVec.Z()*lambdaPy;
154+
double crossY = jetUnitVec.Z()*lambdaPx - jetUnitVec.X()*lambdaPz;
155+
double crossZ = jetUnitVec.X()*lambdaPy - jetUnitVec.Y()*lambdaPx;
156+
double crossProductNorm = std::sqrt(crossX*crossX + crossY*crossY + crossZ*crossZ);
157+
158+
double ringObservable = 3./(lambdaWeakDecayConstant) * ((protonLikeStarUnitVec.X()*crossX
159+
+ protonLikeStarUnitVec.Y()*crossY + protonLikeStarUnitVec.Z()*cross_z)/crossProductNorm);
160+
161+
// Calculating error bars:
162+
double ringObservableSquared = ringObservable*ringObservable;
163+
164+
// Angular variables:
165+
double deltaPhiJet = v0phi - leadingJetPhi;
166+
double deltaThetaJet = ; // 3D angular separation
167+
168+
// Fill ring histograms: (1D, lambda 2D correlations and jet 2D correlations): (TODO)
169+
histos.fill(HIST("Ring/hRingObservableDeltaPhi"), 0);
170+
histos.fill(HIST("Ring/hRingObservableIntegrated"), 0);
171+
172+
histos.fill(HIST("Ring/hRingObservableDeltaPhi"), 0);
173+
histos.fill(HIST("Ring/hRingObservableIntegrated"), 0);
174+
175+
176+
// Extra kinematic criteria for Lambda candidates (removes polarization background):
177+
const bool kinematicLambdaCheck = (v0pt > 0.5 && v0pt < 1.5) && std::abs(lambdaRapidity) < 0.5;
178+
if (kinematicLambdaCheck){
179+
histos.fill(HIST("RingKinematicCuts/hRingObservableDeltaPhi"), 0);
180+
histos.fill(HIST("RingKinematicCuts/hRingObservableIntegrated"), 0);
181+
}
182+
183+
184+
// Extra selection criteria on jet candidates:
185+
const bool kinematicJetCheck = std::abs(leadingJetEta) < 0.5;
186+
if (kinematicJetCheck){ // This is redundant for jets with R=0.4, but for jets with R<0.4 the leading jet may be farther in eta.
187+
188+
}
189+
190+
191+
// Extra selection criteria on Lambda and jet candidates:
192+
if (kinematicLambdaCheck && kinematicJetCheck){
193+
194+
}
195+
196+
197+
} // end v0s loop
198+
} // end collisions
199+
}
200+
};

0 commit comments

Comments
 (0)