CbmRoot
Loading...
Searching...
No Matches
PairAnalysisPairKF.cxx
Go to the documentation of this file.
1/*************************************************************************
2* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3**************************************************************************/
4
6// //
7// PairAnalysis Pair class. Internally it makes use of KFParticle. //
8// //
10
11#include "PairAnalysisPairKF.h"
12
14#include "CbmKFTrack.h"
15#include "CbmMCTrack.h"
16#include "CbmVertex.h"
17
18#include <TDatabasePDG.h>
19
20#include "KFParticle.h"
21#include "PairAnalysisMC.h"
22#include "PairAnalysisTrack.h"
23
25
28 , fPair()
29 , fD1()
30 , fD2()
31{
32 //
33 // Default Constructor
34 //
35}
36
37//______________________________________________
39{
40 //
41 // Copy Constructor
42 //
43 SetTracks(pair.GetFirstDaughter(), pair.GetFirstDaughterPid(), pair.GetSecondDaughter(), pair.GetSecondDaughterPid());
44}
45
46//______________________________________________
48 PairAnalysisTrack* const particle2, Int_t pid2, Char_t type)
49 : PairAnalysisPair(type)
50 , fPair()
51 , fD1()
52 , fD2()
53{
54 //
55 // Constructor with tracks
56 //
57 SetTracks(particle1, pid1, particle2, pid2);
58}
59
60//______________________________________________
62{
63 //
64 // Default Destructor
65 //
66}
67
68//______________________________________________
69void PairAnalysisPairKF::SetTracks(PairAnalysisTrack* const particle1, Int_t pid1, PairAnalysisTrack* const particle2,
70 Int_t pid2)
71{
72 //
73 // set KF daughters and pair
74 // refParticle1 and 2 are the original tracks. In the case of track rotation
75 // they are needed in the framework
76 //
77 // TODO: think about moving the pid assignement to PairAnalysisTrack and use it here
78 // BUT think about mixed events or LS-pairs
79 // const Double_t mpid1 = TDatabasePDG::Instance()->GetParticle(pid1)->Mass(); (FU) unused
80 // const Double_t mpid2 = TDatabasePDG::Instance()->GetParticle(pid2)->Mass(); (FU) unused
81 const Double_t cpid1 = TDatabasePDG::Instance()->GetParticle(pid1)->Charge() * 3;
82 const Double_t cpid2 = TDatabasePDG::Instance()->GetParticle(pid2)->Charge() * 3;
83
84 // match charge of track to pid and set mass accordingly
85 fPid1 = pid1;
86 fPid2 = pid2;
87 // Double_t m1 = mpid1; (FU) unused
88 // Double_t m2 = mpid2; (FU) unused
89 if (particle1->Charge() == cpid2) {
90 // m1=mpid2*; (FU) unused
91 fPid1 = pid2;
92 } //TODO: what about 2e-charges
93 if (particle2->Charge() == cpid1) {
94 // m2=mpid1; (FU) unused
95 fPid2 = pid1;
96 }
97
104
105 // references
106 fRefD1 = particle1;
107 fRefD2 = particle2;
108
109 // build pair
110 fPair.Initialize();
111
112 fPair.AddDaughter(fD1);
113 fPair.AddDaughter(fD2);
114
116 // Double_t mass = TDatabasePDG::Instance()->GetParticle(443)->Mass();
117 // Double_t wdth = TDatabasePDG::Instance()->GetParticle(443)->Width();
118 // if(wdth<1.e-6) wdth=mass*0.01; // width<1keV, then 1% mass resolution
119 // fPair.SetMassConstraint( mass, wdth ); //TODO: take from mother pdg code provided to pairanalysis
120
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 // printf("fill pair weight: %.1f * %.1f = %.1f \n",particle1->GetWeight(),particle2->GetWeight(),fWeight);
137}
138
139//______________________________________________
140void PairAnalysisPairKF::SetMCTracks(const CbmMCTrack* const particle1, const CbmMCTrack* const particle2)
141{
142 //
143 // build MC pair from daughters
144 // no references are set
145 //
146
147 //Initialise covariance matrix and set current parameters to 0.0
148 KFParticle kf1;
149 kf1.Initialize();
150 Float_t* par1 = kf1.Parameters();
151 par1[0] = particle1->GetStartX();
152 par1[1] = particle1->GetStartY();
153 par1[2] = particle1->GetStartZ();
154 par1[3] = particle1->GetPx();
155 par1[4] = particle1->GetPy();
156 par1[5] = particle1->GetPz();
157 par1[6] = particle1->GetEnergy();
158 kf1.SetPDG(particle1->GetPdgCode());
159
160 KFParticle kf2;
161 kf2.Initialize();
162 Float_t* par2 = kf2.Parameters();
163 par2[0] = particle2->GetStartX();
164 par2[1] = particle2->GetStartY();
165 par2[2] = particle2->GetStartZ();
166 par2[3] = particle2->GetPx();
167 par2[4] = particle2->GetPy();
168 par2[5] = particle2->GetPz();
169 par2[6] = particle2->GetEnergy();
170 kf2.SetPDG(particle2->GetPdgCode());
171
172 // build pair
173 fPair.Initialize();
174 fPair.AddDaughter(kf1);
175 fPair.AddDaughter(kf2);
176}
177
178//______________________________________________
179void PairAnalysisPairKF::GetThetaPhiCM(Double_t& thetaHE, Double_t& phiHE, Double_t& thetaCS, Double_t& phiCS) const
180{
181 //
182 // Calculate theta and phi in helicity and Collins-Soper coordinate frame
183 //
184 Double_t px1 = fD1.GetPx();
185 Double_t py1 = fD1.GetPy();
186 Double_t pz1 = fD1.GetPz();
187 Double_t px2 = fD2.GetPx();
188 Double_t py2 = fD2.GetPy();
189 Double_t pz2 = fD2.GetPz();
190 const Double_t d1Mass = TDatabasePDG::Instance()->GetParticle(fPid1)->Mass();
191 const Double_t d2Mass = TDatabasePDG::Instance()->GetParticle(fPid2)->Mass();
192
193 // first & second daughter 4-mom
194 TLorentzVector p1Mom(px1, py1, pz1, TMath::Sqrt(px1 * px1 + py1 * py1 + pz1 * pz1 + d1Mass * d1Mass));
195 TLorentzVector p2Mom(px2, py2, pz2, TMath::Sqrt(px2 * px2 + py2 * py2 + pz2 * pz2 + d2Mass * d2Mass));
196 // mother 4-momentum vector
197 TLorentzVector motherMom = p1Mom + p2Mom;
198
199 PairAnalysisPair::GetThetaPhiCM(motherMom, p1Mom, p2Mom, thetaHE, phiHE, thetaCS, phiCS);
200}
201
202
203//______________________________________________
204Double_t PairAnalysisPairKF::PsiPair(Double_t /*MagField*/) const
205{
206 return 0.; /*
207 //Following idea to use opening of colinear pairs in magnetic field from e.g. PHENIX
208 //to ID conversions. Adapted from TRDv0Info class
209 Double_t x, y;//, z;
210 x = fPair.GetX();
211 y = fPair.GetY();
212 // z = fPair.GetZ();
213
214 Double_t m1[3] = {0,0,0};
215 Double_t m2[3] = {0,0,0};
216
217 m1[0] = fD1.GetPx();
218 m1[1] = fD1.GetPy();
219 m1[2] = fD1.GetPz();
220
221 m2[0] = fD2.GetPx();
222 m2[1] = fD2.GetPy();
223 m2[2] = fD2.GetPz();
224
225 Double_t deltat = 1.;
226 deltat = TMath::ATan(m2[2]/(TMath::Sqrt(m2[0]*m2[0] + m2[1]*m2[1])+1.e-13))-
227 TMath::ATan(m1[2]/(TMath::Sqrt(m1[0]*m1[0] + m1[1]*m1[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis
228
229 Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
230
231 Double_t mom1Prop[3];
232 Double_t mom2Prop[3];
233
234 ExternalTrackParam *d1 = static_cast<ExternalTrackParam*>(fRefD1.GetObject());
235 ExternalTrackParam *d2 = static_cast<ExternalTrackParam*>(fRefD2.GetObject());
236
237 ExternalTrackParam nt(*d1), pt(*d2);
238
239 Double_t fPsiPair = 4.;
240 if(nt.PropagateTo(radiussum,MagField) == 0)//propagate tracks to the outside
241 fPsiPair = -5.;
242 if(pt.PropagateTo(radiussum,MagField) == 0)
243 fPsiPair = -5.;
244 pt.GetPxPyPz(mom1Prop);//Get momentum vectors of tracks after propagation
245 nt.GetPxPyPz(mom2Prop);
246
247
248
249 Double_t pEle =
250 TMath::Sqrt(mom2Prop[0]*mom2Prop[0]+mom2Prop[1]*mom2Prop[1]+mom2Prop[2]*mom2Prop[2]);//absolute momentum val
251 Double_t pPos =
252 TMath::Sqrt(mom1Prop[0]*mom1Prop[0]+mom1Prop[1]*mom1Prop[1]+mom1Prop[2]*mom1Prop[2]);//absolute momentum val
253
254 Double_t scalarproduct =
255 mom1Prop[0]*mom2Prop[0]+mom1Prop[1]*mom2Prop[1]+mom1Prop[2]*mom2Prop[2];//scalar product of propagated posit
256
257 Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
258
259 fPsiPair = TMath::Abs(TMath::ASin(deltat/chipair));
260
261 return fPsiPair;
262 */
263}
264
265//______________________________________________
267{
268 //
269 // Calculate the Armenteros-Podolanski Alpha
270 //
271 Int_t qD1 = fD1.GetQ();
272
273 TVector3 momNeg((qD1 < 0 ? fD1.GetPx() : fD2.GetPx()), (qD1 < 0 ? fD1.GetPy() : fD2.GetPy()),
274 (qD1 < 0 ? fD1.GetPz() : fD2.GetPz()));
275 TVector3 momPos((qD1 < 0 ? fD2.GetPx() : fD1.GetPx()), (qD1 < 0 ? fD2.GetPy() : fD1.GetPy()),
276 (qD1 < 0 ? fD2.GetPz() : fD1.GetPz()));
277 TVector3 momTot(Px(), Py(), Pz());
278
279 Double_t lQlNeg = momNeg.Dot(momTot) / momTot.Mag();
280 Double_t lQlPos = momPos.Dot(momTot) / momTot.Mag();
281
282 return ((lQlPos - lQlNeg) / (lQlPos + lQlNeg));
283}
284
285//______________________________________________
287{
288 //
289 // Calculate the Armenteros-Podolanski Pt
290 //
291 Int_t qD1 = fD1.GetQ();
292
293 TVector3 momNeg((qD1 < 0 ? fD1.GetPx() : fD2.GetPx()), (qD1 < 0 ? fD1.GetPy() : fD2.GetPy()),
294 (qD1 < 0 ? fD1.GetPz() : fD2.GetPz()));
295 TVector3 momTot(Px(), Py(), Pz());
296
297 return (momNeg.Perp(momTot));
298}
299
300//______________________________________________
301Double_t PairAnalysisPairKF::PhivPair(Double_t MagField) const
302{
303 //Following idea to use opening of colinear pairs in magnetic field from e.g. PHENIX
304 //to ID conversions. Angle between ee plane and magnetic field is calculated.
305
306 //Define local buffer variables for leg properties
307 Double_t px1 = -9999., py1 = -9999., pz1 = -9999.;
308 Double_t px2 = -9999., py2 = -9999., pz2 = -9999.;
309
310 if (MagField > 0) {
311 if (fD1.GetQ() > 0) {
312 px1 = fD1.GetPx();
313 py1 = fD1.GetPy();
314 pz1 = fD1.GetPz();
315
316 px2 = fD2.GetPx();
317 py2 = fD2.GetPy();
318 pz2 = fD2.GetPz();
319 }
320 else {
321 px1 = fD2.GetPx();
322 py1 = fD2.GetPy();
323 pz1 = fD2.GetPz();
324
325 px2 = fD1.GetPx();
326 py2 = fD1.GetPy();
327 pz2 = fD1.GetPz();
328 }
329 }
330 else {
331 if (fD1.GetQ() > 0) {
332 px1 = fD2.GetPx();
333 py1 = fD2.GetPy();
334 pz1 = fD2.GetPz();
335
336 px2 = fD1.GetPx();
337 py2 = fD1.GetPy();
338 pz2 = fD1.GetPz();
339 }
340 else {
341 px1 = fD1.GetPx();
342 py1 = fD1.GetPy();
343 pz1 = fD1.GetPz();
344
345 px2 = fD2.GetPx();
346 py2 = fD2.GetPy();
347 pz2 = fD2.GetPz();
348 }
349 }
350
351 Double_t px = px1 + px2;
352 Double_t py = py1 + py2;
353 Double_t pz = pz1 + pz2;
354 Double_t dppair = TMath::Sqrt(px * px + py * py + pz * pz);
355
356 //unit vector of (pep+pem)
357 Double_t pl = dppair;
358 Double_t ux = px / pl;
359 Double_t uy = py / pl;
360 Double_t uz = pz / pl;
361 Double_t ax = uy / TMath::Sqrt(ux * ux + uy * uy);
362 Double_t ay = -ux / TMath::Sqrt(ux * ux + uy * uy);
363
364 //momentum of e+ and e- in (ax,ay,az) axis. Note that az=0 by
365 //definition.
366 //Double_t ptep = iep->Px()*ax + iep->Py()*ay;
367 //Double_t ptem = iem->Px()*ax + iem->Py()*ay;
368
369 Double_t pxep = px1;
370 Double_t pyep = py1;
371 Double_t pzep = pz1;
372 Double_t pxem = px2;
373 Double_t pyem = py2;
374 Double_t pzem = pz2;
375
376 //vector product of pep X pem
377 Double_t vpx = pyep * pzem - pzep * pyem;
378 Double_t vpy = pzep * pxem - pxep * pzem;
379 Double_t vpz = pxep * pyem - pyep * pxem;
380 Double_t vp = sqrt(vpx * vpx + vpy * vpy + vpz * vpz);
381 //Double_t thev = acos(vpz/vp);
382
383 //unit vector of pep X pem
384 Double_t vx = vpx / vp;
385 Double_t vy = vpy / vp;
386 Double_t vz = vpz / vp;
387
388 //The third axis defined by vector product (ux,uy,uz)X(vx,vy,vz)
389 Double_t wx = uy * vz - uz * vy;
390 Double_t wy = uz * vx - ux * vz;
391 //Double_t wz = ux*vy - uy*vx;
392 //Double_t wl = sqrt(wx*wx+wy*wy+wz*wz);
393 // by construction, (wx,wy,wz) must be a unit vector.
394 // measure angle between (wx,wy,wz) and (ax,ay,0). The angle between them
395 // should be small if the pair is conversion
396 //
397 Double_t cosPhiV = wx * ax + wy * ay;
398 Double_t phiv = TMath::ACos(cosPhiV);
399
400 return phiv;
401}
friend fvec sqrt(const fvec &a)
ClassImp(PairAnalysisPairKF) PairAnalysisPairKF
static void SetKFParticleFromStsTrack(CbmStsTrack *track, KFParticle *particle, Int_t pdg=211, Bool_t firstPoint=kTRUE)
double GetPz() const
Definition CbmMCTrack.h:72
double GetPx() const
Definition CbmMCTrack.h:70
double GetStartZ() const
Definition CbmMCTrack.h:75
int32_t GetMotherId() const
Definition CbmMCTrack.h:69
double GetStartX() const
Definition CbmMCTrack.h:73
int32_t GetPdgCode() const
Definition CbmMCTrack.h:68
double GetStartY() const
Definition CbmMCTrack.h:74
double GetPy() const
Definition CbmMCTrack.h:71
double GetEnergy() const
Definition CbmMCTrack.h:162
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)
void SetMCTracks(const CbmMCTrack *const particle1, const CbmMCTrack *const particle2)
virtual Double_t Pz() const
Double_t GetArmPt() const
void GetThetaPhiCM(Double_t &thetaHE, Double_t &phiHE, Double_t &thetaCS, Double_t &phiCS) const
virtual Double_t Px() const
Double_t PhivPair(Double_t MagField) const
Double_t GetArmAlpha() const
virtual Double_t Py() const
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
CbmStsTrack * GetStsTrack() const
CbmMCTrack * GetMCTrack() const
Double_t GetWeight() const
Short_t Charge() const