1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //====================================================================================================================================================
18 // Support class for various common operation on MFT objects
20 // Contact author: antonio.uras@cern.ch
22 //====================================================================================================================================================
24 #include "AliMUONTrackParam.h"
25 #include "AliMUONTrackExtrap.h"
26 #include "AliAODTrack.h"
27 #include "AliAODDimuon.h"
28 #include "TLorentzVector.h"
29 #include "AliMFTConstants.h"
30 #include "TDatabasePDG.h"
33 #include "TObjArray.h"
34 #include "TDecompLU.h"
36 #include "AliMFTAnalysisTools.h"
38 ClassImp(AliMFTAnalysisTools)
40 //====================================================================================================================================================
42 Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2]) {
44 if (!(muon->Pz()!=0)) return kFALSE;
46 AliMUONTrackParam *param = new AliMUONTrackParam();
48 param -> SetNonBendingCoor(muon->XAtDCA());
49 param -> SetBendingCoor(muon->YAtDCA());
50 param -> SetZ(AliMFTConstants::fZEvalKinem);
51 param -> SetNonBendingSlope(muon->Px()/muon->Pz());
52 param -> SetBendingSlope(muon->Py()/muon->Pz());
53 param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
55 AliMUONTrackExtrap::ExtrapToZ(param, z);
56 xy[0] = param->GetNonBendingCoor();
57 xy[1] = param->GetBendingCoor();
65 //====================================================================================================================================================
67 Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem) {
69 if (!(muon->Pz()!=0)) return kFALSE;
71 AliMUONTrackParam *param = new AliMUONTrackParam();
73 param -> SetNonBendingCoor(muon->XAtDCA());
74 param -> SetBendingCoor(muon->YAtDCA());
75 param -> SetZ(AliMFTConstants::fZEvalKinem);
76 param -> SetNonBendingSlope(muon->Px()/muon->Pz());
77 param -> SetBendingSlope(muon->Py()/muon->Pz());
78 param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
80 AliMUONTrackExtrap::ExtrapToZ(param, z);
81 xy[0] = param->GetNonBendingCoor();
82 xy[1] = param->GetBendingCoor();
84 Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
85 Double_t energy = TMath::Sqrt(massMu*massMu + param->Px()*param->Px() + param->Py()*param->Py() + param->Pz()*param->Pz());
87 kinem.SetPxPyPzE(param->Px(), param->Py(), param->Pz(), energy);
95 //====================================================================================================================================================
97 Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem, TMatrixD &cov) {
99 // Extrapolate muon to a given z providing the corresponding (x,y) position and updating kinematics and covariance matrix
101 if (!(muon->Pz()!=0)) return kFALSE;
103 AliMUONTrackParam *param = new AliMUONTrackParam();
105 param -> SetNonBendingCoor(muon->XAtDCA());
106 param -> SetBendingCoor(muon->YAtDCA());
107 param -> SetZ(AliMFTConstants::fZEvalKinem);
108 param -> SetNonBendingSlope(muon->Px()/muon->Pz());
109 param -> SetBendingSlope(muon->Py()/muon->Pz());
110 param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
112 param -> SetCovariances(ConvertCovMatrixAOD2MUON(muon));
114 AliMUONTrackExtrap::ExtrapToZCov(param, z);
115 xy[0] = param->GetNonBendingCoor();
116 xy[1] = param->GetBendingCoor();
118 Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
119 Double_t energy = TMath::Sqrt(massMu*massMu + param->Px()*param->Px() + param->Py()*param->Py() + param->Pz()*param->Pz());
121 kinem.SetPxPyPzE(param->Px(), param->Py(), param->Pz(), energy);
123 cov = param->GetCovariances();
131 //====================================================================================================================================================
133 Bool_t AliMFTAnalysisTools::ExtrapAODMuonToXY(AliAODTrack *muon, Double_t xy[2], Double_t &zFinal, TLorentzVector &kinem, TMatrixD &cov) {
135 // Find the point of closest approach between the muon and the direction parallel to the z-axis defined by the given (x,y)
136 // Provide the z of the above point as weel as the updated kinematics and covariance matrix
138 // We look for the above-defined PCA
140 AliMUONTrackParam *param = new AliMUONTrackParam();
141 param -> SetNonBendingCoor(muon->XAtDCA());
142 param -> SetBendingCoor(muon->YAtDCA());
143 param -> SetZ(AliMFTConstants::fZEvalKinem);
144 param -> SetNonBendingSlope(muon->Px()/muon->Pz());
145 param -> SetBendingSlope(muon->Py()/muon->Pz());
146 param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
148 // here we want to understand in which direction we have to search the minimum...
150 Double_t step = 1.; // initial step, in cm
151 Double_t startPoint = 0.;
153 Double_t r[3]={0}, z[3]={startPoint, startPoint+step, startPoint+2*step};
155 TVector3 **points = new TVector3*[2]; // points[0] for the muon, points[1] for the direction parallel to the z-axis defined by the given (x,y)
157 for (Int_t i=0; i<3; i++) {
158 AliMUONTrackExtrap::ExtrapToZ(param, z[i]);
159 points[0] = new TVector3(param->GetNonBendingCoor(),param->GetBendingCoor(),z[i]);
160 points[1] = new TVector3(xy[0],xy[1],z[i]);
161 r[i] = GetDistanceBetweenPoints(points,2);
162 for (Int_t iMu=0; iMu<2; iMu++) delete points[iMu];
165 Int_t researchDirection = 0;
167 if (r[0]>r[1] && r[1]>r[2]) researchDirection = +1; // towards z positive
168 else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1; // towards z negative
169 else if (r[0]<r[1] && r[1]>r[2]) {
170 printf("E-AliMFTAnalysisTools::ExtrapAODMuonToXY: Point of closest approach cannot be found (no minima)\n");
176 while (TMath::Abs(researchDirection)>0.5) {
178 if (researchDirection>0) {
181 z[2] = z[1]+researchDirection*step;
186 z[0] = z[1]+researchDirection*step;
188 if (TMath::Abs(z[0])>900.) {
189 printf("E-AliMFTAnalysisTools::ExtrapAODMuonToXY: Point of closest approach cannot be found (no minima in the fiducial region)\n");
195 for (Int_t i=0; i<3; i++) {
196 AliMUONTrackExtrap::ExtrapToZ(param, z[i]);
197 points[0] = new TVector3(param->GetNonBendingCoor(),param->GetBendingCoor(),z[i]);
198 points[1] = new TVector3(xy[0],xy[1],z[i]);
199 r[i] = GetDistanceBetweenPoints(points,2);
200 for (Int_t iMu=0; iMu<2; iMu++) delete points[iMu];
204 if (r[0]>r[1] && r[1]>r[2]) researchDirection = +1; // towards z positive
205 else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1; // towards z negative
209 // now we now that the minimum is between z[0] and z[2] and we search for it
212 while (step>AliMFTConstants::fPrecisionPointOfClosestApproach) {
215 for (Int_t i=0; i<3; i++) {
216 AliMUONTrackExtrap::ExtrapToZ(param, z[i]);
217 points[0] = new TVector3(param->GetNonBendingCoor(),param->GetBendingCoor(),z[i]);
218 points[1] = new TVector3(xy[0],xy[1],z[i]);
219 r[i] = GetDistanceBetweenPoints(points,2);
220 for (Int_t iMu=0; iMu<2; iMu++) delete points[iMu];
222 if (r[0]<r[1]) z[1] = z[0];
223 else if (r[2]<r[1]) z[1] = z[2];
229 Double_t xyMuon[2] = {0};
230 ExtrapAODMuonToZ(muon, zFinal, xyMuon, kinem, cov);
236 //====================================================================================================================================================
238 Bool_t AliMFTAnalysisTools::GetAODMuonOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv, Double_t &offset) {
240 Double_t xy[2] = {0};
241 ExtrapAODMuonToZ(muon, zv, xy);
243 offset = TMath::Sqrt((xv-xy[0])*(xv-xy[0]) + (yv-xy[1])*(yv-xy[1]));
249 //====================================================================================================================================================
251 Bool_t AliMFTAnalysisTools::GetAODMuonOffsetZ(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv, Double_t &offset) {
253 Double_t xy[2] = {xv, yv};
255 TLorentzVector kinem(0,0,0,0);
258 ExtrapAODMuonToXY(muon, xy, zFinal, kinem, cov);
260 offset = TMath::Abs(zFinal - zv);
266 //====================================================================================================================================================
268 Bool_t AliMFTAnalysisTools::GetAODMuonWeightedOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv, Double_t &offset) {
270 Double_t xy[2] = {0};
271 TLorentzVector kinem(0,0,0,0);
274 ExtrapAODMuonToZ(muon, zv, xy, kinem, cov);
276 TMatrixD covCoordinates(2,2);
277 covCoordinates(0,0) = cov(0,0);
278 covCoordinates(0,1) = cov(0,2);
279 covCoordinates(1,0) = cov(2,0);
280 covCoordinates(1,1) = cov(2,2);
282 if (TDecompLU::InvertLU(covCoordinates,covCoordinates.GetTol(),0)) {
284 TMatrixD covCoordinatesInverse = covCoordinates;
285 Double_t dX = xy[0] - xv;
286 Double_t dY = xy[1] - yv;
288 offset = TMath::Sqrt(0.5*(dX*dX*covCoordinatesInverse(0,0) +
289 dY*dY*covCoordinatesInverse(1,1) +
290 2.*dX*dY*covCoordinatesInverse(0,1)));
300 //====================================================================================================================================================
302 Double_t AliMFTAnalysisTools::GetPseudoProperDecayTimeXY(Double_t xVtx, Double_t yVtx,
303 Double_t xDimu, Double_t yDimu,
304 Double_t mDimu, Double_t ptDimu) {
306 // pseudo-proper decay time of a particle produced in the primary vertex and decaying into a dimuon (+ X)
307 // evaluated using the transverse degree of freedom of the decay topology
310 Double_t decayLengthXY = TMath::Sqrt((xVtx-xDimu)*(xVtx-xDimu)+(yVtx-yDimu)*(yVtx-yDimu));
311 return (decayLengthXY * mDimu/ptDimu)/TMath::Ccgs()*1E12; // in ps
318 //====================================================================================================================================================
320 Double_t AliMFTAnalysisTools::GetPseudoProperDecayTimeZ(Double_t zVtx,
322 Double_t mDimu, Double_t pzDimu) {
324 // pseudo-proper decay time of a particle produced in the primary vertex and decaying into a dimuon (+ X)
325 // evaluated using the longitudinal degree of freedom of the decay topology
328 Double_t decayLengthZ = zDimu - zVtx;
329 return (decayLengthZ * mDimu/pzDimu)/TMath::Ccgs()*1E12; // in ps
336 //====================================================================================================================================================
338 Bool_t AliMFTAnalysisTools::CalculatePCA(AliAODDimuon *dimuon, Double_t *pca, Double_t &pcaQuality, TLorentzVector &kinem) {
340 TObjArray *muons = new TObjArray();
341 muons -> Add(dimuon->GetMu(0));
342 muons -> Add(dimuon->GetMu(1));
344 Bool_t result = CalculatePCA(muons, pca, pcaQuality, kinem);
350 //====================================================================================================================================================
352 Bool_t AliMFTAnalysisTools::CalculatePCA(TObjArray *muons, Double_t *pca, Double_t &pcaQuality, TLorentzVector &kinem) {
354 const Int_t nMuons = muons->GetEntriesFast();
355 if (nMuons<2 || nMuons>AliMFTConstants::fNMaxMuonsForPCA) {
356 printf("W-AliMFTAnalysisTools::CalculatePCA: number of muons not valid\n");
360 Double_t fXPointOfClosestApproach=0, fYPointOfClosestApproach=0, fZPointOfClosestApproach=0;
362 AliAODTrack *muon[AliMFTConstants::fNMaxMuonsForPCA] = {0};
363 AliMUONTrackParam *param[AliMFTConstants::fNMaxMuonsForPCA] = {0};
365 // Finding AliMUONTrackParam objects for each muon
367 for (Int_t iMu=0; iMu<nMuons; iMu++) {
368 muon[iMu] = (AliAODTrack*) muons->At(iMu);
369 if (TMath::Abs(muon[iMu]->Pz())<1.e-6) {
370 for(Int_t i=0;i<iMu;i++) delete param[i];
373 param[iMu] = new AliMUONTrackParam();
374 param[iMu] -> SetNonBendingCoor(muon[iMu]->XAtDCA());
375 param[iMu] -> SetBendingCoor(muon[iMu]->YAtDCA());
376 param[iMu] -> SetZ(AliMFTConstants::fZEvalKinem);
377 param[iMu] -> SetNonBendingSlope(muon[iMu]->Px()/muon[iMu]->Pz());
378 param[iMu] -> SetBendingSlope(muon[iMu]->Py()/muon[iMu]->Pz());
379 param[iMu] -> SetInverseBendingMomentum( muon[iMu]->Charge() * (1./muon[iMu]->Pz()) / (TMath::Sqrt(1+TMath::Power(muon[iMu]->Py()/muon[iMu]->Pz(),2))) );
382 // here we want to understand in which direction we have to search the minimum...
384 Double_t step = 1.; // initial step, in cm
385 Double_t startPoint = 0.;
387 Double_t r[3]={0}, z[3]={startPoint, startPoint+step, startPoint+2*step};
389 TVector3 **points = new TVector3*[AliMFTConstants::fNMaxMuonsForPCA];
391 for (Int_t i=0; i<3; i++) {
392 for (Int_t iMu=0; iMu<nMuons; iMu++) {
393 AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
394 points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
396 r[i] = GetDistanceBetweenPoints(points,nMuons);
397 for (Int_t iMu=0; iMu<nMuons; iMu++) delete points[iMu];
400 Int_t researchDirection = 0;
402 if (r[0]>r[1] && r[1]>r[2]) researchDirection = +1; // towards z positive
403 else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1; // towards z negative
404 else if (r[0]<r[1] && r[1]>r[2]) {
405 printf("E-AliMFTAnalysisTools::CalculatePCA: Point of closest approach cannot be found for dimuon (no minima)\n");
406 for (Int_t iMu=0;iMu<nMuons;iMu++) delete param[iMu];
411 while (TMath::Abs(researchDirection)>0.5) {
413 if (researchDirection>0) {
416 z[2] = z[1]+researchDirection*step;
421 z[0] = z[1]+researchDirection*step;
423 if (TMath::Abs(z[0])>900.) {
424 printf("E-AliMFTAnalysisTools::CalculatePCA: Point of closest approach cannot be found for dimuon (no minima in the fiducial region)\n");
425 for (Int_t iMu=0;iMu<nMuons;iMu++) delete param[iMu];
430 for (Int_t i=0; i<3; i++) {
431 for (Int_t iMu=0; iMu<nMuons; iMu++) {
432 AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
433 points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
435 r[i] = GetDistanceBetweenPoints(points,nMuons);
436 for (Int_t iMu=0;iMu<nMuons;iMu++) delete points[iMu];
439 if (r[0]>r[1] && r[1]>r[2]) researchDirection = +1; // towards z positive
440 else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1; // towards z negative
444 // now we now that the minimum is between z[0] and z[2] and we search for it
447 while (step>AliMFTConstants::fPrecisionPointOfClosestApproach) {
450 for (Int_t i=0; i<3; i++) {
451 for (Int_t iMu=0; iMu<nMuons; iMu++) {
452 AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
453 points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
455 r[i] = GetDistanceBetweenPoints(points,nMuons);
456 for (Int_t iMu=0;iMu<nMuons;iMu++) delete points[iMu];
458 if (r[0]<r[1]) z[1] = z[0];
459 else if (r[2]<r[1]) z[1] = z[2];
463 // Once z of minimum is found, we evaluate the x and y coordinates by averaging over the contributing tracks
465 fZPointOfClosestApproach = z[1];
466 fXPointOfClosestApproach = 0.;
467 fYPointOfClosestApproach = 0.;
468 for (Int_t iMu=0; iMu<nMuons; iMu++) {
469 AliMUONTrackExtrap::ExtrapToZ(param[iMu], fZPointOfClosestApproach);
470 fXPointOfClosestApproach += param[iMu]->GetNonBendingCoor();
471 fYPointOfClosestApproach += param[iMu]->GetBendingCoor();
473 fXPointOfClosestApproach /= Double_t(nMuons);
474 fYPointOfClosestApproach /= Double_t(nMuons);
476 pca[0] = fXPointOfClosestApproach;
477 pca[1] = fYPointOfClosestApproach;
478 pca[2] = fZPointOfClosestApproach;
480 // Evaluating the kinematics of the N-muon
482 Double_t pTot[3] = {0};
484 Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
485 for (Int_t iMu=0; iMu<nMuons; iMu++) {
486 pTot[0] += param[iMu]->Px();
487 pTot[1] += param[iMu]->Py();
488 pTot[2] += param[iMu]->Pz();
489 ene += TMath::Sqrt(massMu*massMu + param[iMu]->Px()*param[iMu]->Px() + param[iMu]->Py()*param[iMu]->Py() + param[iMu]->Pz()*param[iMu]->Pz());
492 kinem.SetPxPyPzE(pTot[0], pTot[1], pTot[2], ene);
494 // Evaluating the PCA quality of the N-muon
496 Double_t sum=0.,squareSum=0.;
497 for (Int_t iMu=0; iMu<nMuons; iMu++) {
498 Double_t wOffset = 0;
499 if (!GetAODMuonWeightedOffset(muon[iMu],fXPointOfClosestApproach, fYPointOfClosestApproach, fZPointOfClosestApproach, wOffset)) {
500 for(Int_t jMu=0;jMu<nMuons;jMu++) delete param[jMu];
504 Double_t f = TMath::Exp(-0.5 * wOffset);
508 if (sum > 0.) pcaQuality = (sum-squareSum/sum) / (nMuons-1);
509 else pcaQuality = 0.;
511 for(Int_t iMu=0;iMu<nMuons;iMu++) delete param[iMu];
517 //=========================================================================================================================
519 Double_t AliMFTAnalysisTools::GetDistanceBetweenPoints(TVector3 **points, Int_t nPoints) {
521 if (nPoints>AliMFTConstants::fNMaxMuonsForPCA) {
522 printf("W-AliMFTAnalysisTools::GetDistanceBetweenPoints: number of points not valid\n");
526 if (nPoints<2) return 0.;
527 if (nPoints<3) return TMath::Sqrt( (points[0]->X()-points[1]->X()) * (points[0]->X()-points[1]->X()) +
528 (points[0]->Y()-points[1]->Y()) * (points[0]->Y()-points[1]->Y()) +
529 (points[0]->Z()-points[1]->Z()) * (points[0]->Z()-points[1]->Z()) );
531 const Int_t nEdgesMax = ((AliMFTConstants::fNMaxMuonsForPCA) * (AliMFTConstants::fNMaxMuonsForPCA - 1)) / 2;
533 Int_t startID[nEdgesMax] = {0};
534 Int_t stopID[nEdgesMax] = {0};
535 Double_t edgeLength[nEdgesMax] = {0};
537 Bool_t pointStatus[AliMFTConstants::fNMaxMuonsForPCA] = {0};
540 for (Int_t i=0; i<nPoints-1; i++) {
541 for (Int_t j=i+1; j<nPoints; j++) {
542 edgeLength[nEdges] = TMath::Sqrt( (points[i]->X()-points[j]->X()) * (points[i]->X()-points[j]->X()) +
543 (points[i]->Y()-points[j]->Y()) * (points[i]->Y()-points[j]->Y()) +
544 (points[i]->Z()-points[j]->Z()) * (points[i]->Z()-points[j]->Z()) );
556 for (Int_t iEdge=0; iEdge<nEdges-1; iEdge++) {
557 min = edgeLength[iEdge];
559 for (Int_t j=iEdge+1; j<nEdges; j++) {
560 if (edgeLength[j]<min) {
568 Double_t edgeLengthMin = edgeLength[iMin];
569 Int_t startIDmin = startID[iMin];
570 Int_t stopIDmin = stopID[iMin];
572 edgeLength[iMin] = edgeLength[iEdge];
573 startID[iMin] = startID[iEdge];
574 stopID[iMin] = stopID[iEdge];
576 edgeLength[iEdge] = edgeLengthMin;
577 startID[iEdge] = startIDmin;
578 stopID[iEdge] = stopIDmin;
586 Double_t length = 0.;
587 for (Int_t i=0; i<nEdges; i++) {
588 if (!(pointStatus[startID[i]] && pointStatus[stopID[i]])) {
589 pointStatus[startID[i]] = kTRUE;
590 pointStatus[stopID[i]] = kTRUE;
591 length += edgeLength[i];
599 //====================================================================================================================================================
601 void AliMFTAnalysisTools::ConvertCovMatrixMUON2AOD(const TMatrixD& covMUON, Double_t covAOD[21]) {
603 // Converts the cov matrix from the MUON format (TMatrixD) to the AOD one (Double_t[21])
605 // Cov(x,x) ... : cv[0]
606 // Cov(x,slopeX) ... : cv[1] cv[2]
607 // Cov(x,y) ... : cv[3] cv[4] cv[5]
608 // Cov(x,slopeY) ... : cv[6] cv[7] cv[8] cv[9]
609 // Cov(x,invP_yz) ... : cv[10] cv[11] cv[12] cv[13] cv[14]
610 // not-used ... : cv[15] cv[16] cv[17] cv[18] cv[19] cv[20]
612 covAOD[0] = covMUON(0,0);
614 covAOD[1] = covMUON(1,0);
615 covAOD[2] = covMUON(1,1);
617 covAOD[3] = covMUON(2,0);
618 covAOD[4] = covMUON(2,1);
619 covAOD[5] = covMUON(2,2);
621 covAOD[6] = covMUON(3,0);
622 covAOD[7] = covMUON(3,1);
623 covAOD[8] = covMUON(3,2);
624 covAOD[9] = covMUON(3,3);
626 covAOD[10] = covMUON(4,0);
627 covAOD[11] = covMUON(4,1);
628 covAOD[12] = covMUON(4,2);
629 covAOD[13] = covMUON(4,3);
630 covAOD[14] = covMUON(4,4);
641 //====================================================================================================================================================
643 const TMatrixD AliMFTAnalysisTools::ConvertCovMatrixAOD2MUON(AliAODTrack *muon) {
645 Double_t covAOD[21] = {0};
646 muon -> GetCovarianceXYZPxPyPz(covAOD);
648 TMatrixD covMUON(5,5);
650 covMUON(0,0) = covAOD[0];
652 covMUON(1,0) = covAOD[1];
653 covMUON(1,1) = covAOD[2];
655 covMUON(2,0) = covAOD[3];
656 covMUON(2,1) = covAOD[4];
657 covMUON(2,2) = covAOD[5];
659 covMUON(3,0) = covAOD[6];
660 covMUON(3,1) = covAOD[7];
661 covMUON(3,2) = covAOD[8];
662 covMUON(3,3) = covAOD[9];
664 covMUON(4,0) = covAOD[10];
665 covMUON(4,1) = covAOD[11];
666 covMUON(4,2) = covAOD[12];
667 covMUON(4,3) = covAOD[13];
668 covMUON(4,4) = covAOD[14];
674 //====================================================================================================================================================
676 Bool_t AliMFTAnalysisTools::IsCorrectMatch(AliAODTrack *muon) {
678 for (Int_t iPlane=0; iPlane<AliMFTConstants::fNMaxPlanes; iPlane++) if (IsWrongCluster(muon, iPlane)) return kFALSE;
683 //====================================================================================================================================================
685 TString AliMFTAnalysisTools::GetGenerator(Int_t label, AliAODMCHeader* header) {
687 // get the name of the generator that produced a given particle
689 Int_t partCounter = 0;
690 TList *genHeaders = header->GetCocktailHeaders();
691 Int_t nGenHeaders = genHeaders->GetEntries();
693 for (Int_t i=0; i<nGenHeaders; i++){
694 AliGenEventHeader *gh = (AliGenEventHeader*) genHeaders->At(i);
695 TString genName = gh->GetName();
696 Int_t nPart = gh->NProduced();
697 if (label>=partCounter && label<(partCounter+nPart)) return genName;
698 partCounter += nPart;
706 //====================================================================================================================================================
708 void AliMFTAnalysisTools::GetTrackPrimaryGenerator(AliAODTrack *track, AliAODMCHeader *header, TClonesArray *arrayMC, TString &nameGen) {
710 // method to check if a track comes from a given generator
712 Int_t label = TMath::Abs(track->GetLabel());
713 nameGen = GetGenerator(label,header);
715 // In case the particle is not primary nameGen will contain blank spaces. In this case, we search backward for the primary which originated the chain
717 while (nameGen.IsWhitespace()) {
718 AliAODMCParticle *mcPart = (AliAODMCParticle*) arrayMC->At(label);
720 printf("AliMFTAnalysisTools::GetTrackPrimaryGenerator - BREAK: No valid AliAODMCParticle at label %i\n",label);
723 Int_t motherLabel = mcPart->GetMother();
724 if (motherLabel < 0) {
725 printf("AliMFTAnalysisTools::GetTrackPrimaryGenerator - BREAK: Reached primary particle without valid mother\n");
729 nameGen = GetGenerator(label,header);
736 //====================================================================================================================================================
738 Bool_t AliMFTAnalysisTools::IsTrackInjected(AliAODTrack *track, AliAODMCHeader *header, TClonesArray *arrayMC){
740 // method to check if a track comes from the signal event or from the underlying Hijing event
744 GetTrackPrimaryGenerator(track,header,arrayMC,nameGen);
746 if (nameGen.IsWhitespace() || nameGen.Contains("ijing")) return kFALSE;
751 //====================================================================================================================================================