CbmRoot
Loading...
Searching...
No Matches
PairAnalysisPairLV.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2019 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4/*
5
6 PairAnalysisPair class that internally makes use of TLorentzVector.
7
8*/
9// //
11
12
13#include "PairAnalysisPairLV.h"
14
15#include "CbmMCTrack.h"
16
17#include <TDatabasePDG.h>
18
19#include "PairAnalysisMC.h"
20#include "PairAnalysisTrack.h"
21
23
26 , fPairPos()
27 , fPair()
28 , fD1()
29 , fD2()
30{
31 //
32 // Default Constructor
33 //
34}
35
36//______________________________________________
38 : PairAnalysisPair(pair)
39 , fPairPos()
40 , fPair()
41 , fD1()
42 , fD2()
43{
44 //
45 // Copy Constructor
46 //
47 SetTracks(pair.GetFirstDaughter(), pair.GetFirstDaughterPid(), pair.GetSecondDaughter(), pair.GetSecondDaughterPid());
48}
49
50//______________________________________________
52 PairAnalysisTrack* const particle2, Int_t pid2, Char_t type)
53 : PairAnalysisPair(type)
54 , fPairPos()
55 , fPair()
56 , fD1()
57 , fD2()
58{
59 //
60 // Constructor with tracks
61 //
62 SetTracks(particle1, pid1, particle2, pid2);
63}
64
65//______________________________________________
67{
68 //
69 // Default Destructor
70 //
71}
72
73//______________________________________________
74void PairAnalysisPairLV::SetTracks(PairAnalysisTrack* const particle1, Int_t pid1, PairAnalysisTrack* const particle2,
75 Int_t pid2)
76{
77 //
78 // set TLorentzVector daughters and pair
79 // refParticle1 and 2 are the original tracks. In the case of track rotation
80 // they are needed in the framework
81 //
82
83 //vvv
84 // TODO: think about moving the pid assignement to PairAnalysisTrack and use it here
85 // BUT what about mixed events or LS-pairs
86 const Double_t mpid1 = TDatabasePDG::Instance()->GetParticle(pid1)->Mass();
87 const Double_t mpid2 = TDatabasePDG::Instance()->GetParticle(pid2)->Mass();
88 const Double_t cpid1 = TDatabasePDG::Instance()->GetParticle(pid1)->Charge() * 3;
89 const Double_t cpid2 = TDatabasePDG::Instance()->GetParticle(pid2)->Charge() * 3;
90
91 // match charge of track to pid and set mass accordingly
92 fPid1 = pid1;
93 fPid2 = pid2;
94 Double_t m1 = mpid1;
95 Double_t m2 = mpid2;
96 if (particle1->Charge() == cpid2) {
97 m1 = mpid2;
98 fPid1 = pid2;
99 } //TODO: what about 2e-charges
100 if (particle2->Charge() == cpid1) {
101 m2 = mpid1;
102 fPid2 = pid1;
103 }
104
105 // Calculate Energy per particle by hand
106 Double_t e1 = TMath::Sqrt(m1 * m1 + particle1->Px() * particle1->Px() + particle1->Py() * particle1->Py()
107 + particle1->Pz() * particle1->Pz());
108
109 Double_t e2 = TMath::Sqrt(m2 * m2 + particle2->Px() * particle2->Px() + particle2->Py() * particle2->Py()
110 + particle2->Pz() * particle2->Pz());
111
112 fRefD1 = particle1;
113 fRefD2 = particle2;
114 fD1.SetPxPyPzE(particle1->Px(), particle1->Py(), particle1->Pz(), e1);
115 fD2.SetPxPyPzE(particle2->Px(), particle2->Py(), particle2->Pz(), e2);
116 //^^^ this should become obsolete
117
118 // build pair
119 fPair = (fD1 + fD2);
120 fPairPos = (*particle1->GetPosition() + *particle2->GetPosition());
121 fCharge = (particle1->Charge() * particle2->Charge());
122 fWeight = particle1->GetWeight() * particle2->GetWeight();
123
124 //Check if both particles come from the same mother -> then only use one weight
126 if (mc->HasMC() && particle1->GetMCTrack() && particle2->GetMCTrack()) {
127 CbmMCTrack* particle1MC = particle1->GetMCTrack();
128 CbmMCTrack* particle2MC = particle2->GetMCTrack();
129 Int_t mother1Id = particle1MC->GetMotherId();
130 Int_t mother2Id = particle2MC->GetMotherId();
131 CbmMCTrack* mother1 = mc->GetMCTrackFromMCEvent(mother1Id);
132 CbmMCTrack* mother2 = mc->GetMCTrackFromMCEvent(mother2Id);
133 if (mother1 && mother2 && (mother1Id == mother2Id)) fWeight = particle1->GetWeight();
134 }
135
136
137 // printf("fill pair weight: %.1f * %.1f = %.1f \n",particle1->GetWeight(),particle2->GetWeight(),fWeight);
138}
139
140//______________________________________________
141void PairAnalysisPairLV::SetMCTracks(const CbmMCTrack* const particle1, const CbmMCTrack* const particle2)
142{
143 //
144 // build MC pair from TLorentzVector daughters
145 // no references are set
146 //
147 particle1->Get4Momentum(fD1);
148 particle2->Get4Momentum(fD2);
149 fPair = (fD1 + fD2);
150 TLorentzVector fD1Pos(particle1->GetStartX(), particle1->GetStartY(), particle1->GetStartZ(), particle1->GetStartT());
151 TLorentzVector fD2Pos(particle2->GetStartX(), particle2->GetStartY(), particle2->GetStartZ(), particle2->GetStartT());
152 fPairPos = (fD1Pos + fD2Pos);
153}
154
155//______________________________________________
156// Int_t PairAnalysisPairLV::Charge() const
157// {
158// return (dynamic_cast<PairAnalysisTrack*>(fRefD1.GetObject())->Charge() +
159// dynamic_cast<PairAnalysisTrack*>(fRefD2.GetObject())->Charge());
160// }
161
162//______________________________________________
163void PairAnalysisPairLV::GetThetaPhiCM(Double_t& thetaHE, Double_t& phiHE, Double_t& thetaCS, Double_t& phiCS) const
164{
165 //
166 // Calculate theta and phi in helicity and Collins-Soper coordinate frame
167 //
168
169 TLorentzVector motherMom(fPair);
170 TLorentzVector p1Mom(fD1);
171 TLorentzVector p2Mom(fD2);
172 PairAnalysisPair::GetThetaPhiCM(motherMom, p1Mom, p2Mom, thetaHE, phiHE, thetaCS, phiCS);
173}
174
175
176//______________________________________________
177Double_t PairAnalysisPairLV::PsiPair(Double_t /*MagField*/) const
178{
179 //Following idea to use opening of colinear pairs in magnetic field from e.g. PHENIX
180 //to ID conversions. Adapted from AliTRDv0Info class
181 //TODO: adapt and get magnetic field
182 /* (FU) not used
183 Double_t x, y;//, z;
184 x = fPair.X();
185 y = fPair.Y();
186 // z = fPair.Z();
187*/
188 Double_t m1[3] = {0, 0, 0};
189 Double_t m2[3] = {0, 0, 0};
190
191 m1[0] = fD1.Px();
192 m1[1] = fD1.Py();
193 m1[2] = fD1.Pz();
194
195 m2[0] = fD2.Px();
196 m2[1] = fD2.Py();
197 m2[2] = fD2.Pz();
198
199 Double_t deltat = 1.;
200 //difference of angles of the two daughter tracks with z-axis
201 deltat = TMath::ATan(m2[2] / (TMath::Sqrt(m2[0] * m2[0] + m2[1] * m2[1]) + 1.e-13))
202 - TMath::ATan(m1[2] / (TMath::Sqrt(m1[0] * m1[0] + m1[1] * m1[1]) + 1.e-13));
203
204 // Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
205
206 Double_t mom1Prop[3] = {0., 0., 0.};
207 Double_t mom2Prop[3] = {0., 0., 0.};
208
209 // TODO: adapt code
210 Double_t fPsiPair = 4.;
211 /*
212 AliExternalTrackParam *d1 = static_cast<AliExternalTrackParam*>(fRefD1.GetObject());
213 AliExternalTrackParam *d2 = static_cast<AliExternalTrackParam*>(fRefD2.GetObject());
214 AliExternalTrackParam nt(*d1), pt(*d2);
215
216 if(nt.PropagateTo(radiussum,MagField) == 0)//propagate tracks to the outside
217 fPsiPair = -5.;
218 if(pt.PropagateTo(radiussum,MagField) == 0)
219 fPsiPair = -5.;
220 pt.GetPxPyPz(mom1Prop);//Get momentum vectors of tracks after propagation
221 nt.GetPxPyPz(mom2Prop);
222 */
223
224 // absolute momentum values
225 Double_t pEle = TMath::Sqrt(mom2Prop[0] * mom2Prop[0] + mom2Prop[1] * mom2Prop[1] + mom2Prop[2] * mom2Prop[2]);
226 Double_t pPos = TMath::Sqrt(mom1Prop[0] * mom1Prop[0] + mom1Prop[1] * mom1Prop[1] + mom1Prop[2] * mom1Prop[2]);
227 //scalar product of propagated posit
228 Double_t scalarproduct = mom1Prop[0] * mom2Prop[0] + mom1Prop[1] * mom2Prop[1] + mom1Prop[2] * mom2Prop[2];
229 //Angle between propagated daughter tracks
230 Double_t chipair = TMath::ACos(scalarproduct / (pEle * pPos));
231
232 fPsiPair = TMath::Abs(TMath::ASin(deltat / chipair));
233
234 return fPsiPair;
235}
236
237//______________________________________________
239{
240 //
241 // Calculate the Armenteros-Podolanski Alpha
242 //
243 Int_t qD1 = dynamic_cast<PairAnalysisTrack*>(fRefD1.GetObject())->Charge() > 0;
244 TVector3 momNeg = (qD1 < 0 ? fD1.Vect() : fD2.Vect());
245 TVector3 momPos = (qD1 < 0 ? fD2.Vect() : fD1.Vect());
246 TVector3 momTot(Px(), Py(), Pz());
247
248 Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag();
249 Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag();
250
251 return ((lQlPos - lQlNeg) / (lQlPos + lQlNeg));
252}
253
254//______________________________________________
256{
257 //
258 // Calculate the Armenteros-Podolanski Pt
259 //
260 Int_t qD1 = dynamic_cast<PairAnalysisTrack*>(fRefD1.GetObject())->Charge() > 0;
261 TVector3 momNeg = (qD1 < 0 ? fD1.Vect() : fD2.Vect());
262 TVector3 momTot(Px(), Py(), Pz());
263 return (momNeg.Perp(momTot));
264}
265
266//______________________________________________
267Double_t PairAnalysisPairLV::PhivPair(Double_t MagField) const
268{
279 Int_t qD1 = 0;
280 if (fRefD1.GetObject()) qD1 = dynamic_cast<PairAnalysisTrack*>(fRefD1.GetObject())->Charge() > 0;
281 // TODO add mc charge (no fRefD1.GetObject())
282 TVector3 p1;
283 TVector3 p2;
284
285 // L1FieldValue bfield = CbmL1::Instance()->algo->GetvtxFieldValue();
286 // printf("l1 field values: %f %f %f \n",bfield.x[0],bfield.y[0],bfield.z[0]);
287 // if(bfield.y[0]>0){
288 if (MagField < 0) {
289 p1 = (qD1 > 0 ? fD1.Vect() : fD2.Vect());
290 p2 = (qD1 > 0 ? fD2.Vect() : fD1.Vect());
291 }
292 else {
293 p2 = (qD1 > 0 ? fD1.Vect() : fD2.Vect());
294 p1 = (qD1 > 0 ? fD2.Vect() : fD1.Vect());
295 }
296
297 //unit vector of (pep+pem)
298 TVector3 u = fPair.Vect();
299 u.SetMag(1.); // normalize
300
301 //vector product of pep X pem (perpendicular to the pair)
302 TVector3 vpm = p1.Cross(p2);
303 vpm.SetMag(1.); // normalize
304
305 //The third axis defined by vector product (ux,uy,uz)X(vx,vy,vz)
306 // by construction, (wx,wy,wz) must be a unit vector.
307 TVector3 w = u.Cross(vpm);
308
309 // unit vector in xz-plane (perpendicular to B-field)
310 Double_t ax = u.Pz() / TMath::Sqrt(u.Px() + u.Px() + u.Pz() + u.Pz()); // =sin(alpha_xz)
311 Double_t ay = 0.; // by defintion
312 Double_t az = u.Pz() / TMath::Sqrt(u.Px() + u.Px() + u.Pz() + u.Pz()); // =cos(alpha_xz+180)
313 TVector3 a(ax, ay, az);
314
315 // measure angle between (wx,wy,wz) and (ax,ay,0). The angle between them
316 // should be small if the pair is conversion
317 // Double_t cosPhiV = w.Px()*ax + w.Py()*ay; // angle btw w and a
318 // Double_t phiv = TMath::ACos(cosPhiV);
319 Double_t phiv = w.Angle(a);
320
321 return phiv;
322}
323
324//_______________________________________________
326{
327 //
328 // Rotate one of the legs according to the track rotator settings
329 //
330
331 Double_t rotAngle = rot->GetAngle();
332 Double_t rotCharge = rot->GetCharge();
333
335 if (!first) return;
336
337 //Printf("\n before rotation:");
338 //fD1.Print("");
339 //fD2.Print("");
340
343 if (first->Charge() > 0) fD1.RotateZ(rotAngle);
344 else
345 fD2.RotateZ(rotAngle);
346 }
347
350 if (first->Charge() > 0) fD1.RotateZ(rotAngle);
351 else
352 fD2.RotateZ(rotAngle);
353 }
354 // Printf("after rotation:");
355 //fD1.Print("");
356 //fD2.Print("");
357
358 // rebuild pair
359 fPair = (fD1 + fD2);
360}
bool first
ClassImp(PairAnalysisPairLV) PairAnalysisPairLV
double GetStartT() const
Definition CbmMCTrack.h:76
double GetStartZ() const
Definition CbmMCTrack.h:75
int32_t GetMotherId() const
Definition CbmMCTrack.h:69
double GetStartX() const
Definition CbmMCTrack.h:73
void Get4Momentum(TLorentzVector &momentum) const
Definition CbmMCTrack.h:173
double GetStartY() const
Definition CbmMCTrack.h:74
static PairAnalysisMC * Instance()
Bool_t HasMC() const
CbmMCTrack * GetMCTrackFromMCEvent(Int_t label) const
void SetTracks(PairAnalysisTrack *const particle1, Int_t pid1, PairAnalysisTrack *const particle2, Int_t pid2)
virtual Double_t Py() const
virtual Double_t Pz() const
virtual Double_t Px() const
void GetThetaPhiCM(Double_t &thetaHE, Double_t &phiHE, Double_t &thetaCS, Double_t &phiCS) const
virtual void RotateTrack(PairAnalysisTrackRotator *rot)
Double_t GetArmAlpha() const
Double_t GetArmPt() const
Double_t PhivPair(Double_t MagField) const
void SetMCTracks(const CbmMCTrack *const particle1, const CbmMCTrack *const particle2)
Double_t PsiPair(Double_t MagField) const
virtual void GetThetaPhiCM(Double_t &thetaHE, Double_t &phiHE, Double_t &thetaCS, Double_t &phiCS) const =0
TRef fRefD1
beam energy
PairAnalysisTrack * GetFirstDaughter() const
ERotationType GetRotationType() const
CbmMCTrack * GetMCTrack() const
TLorentzVector * GetPosition()
Double_t Px() const
Double_t GetWeight() const
Double_t Py() const
Short_t Charge() const
Double_t Pz() const