Analysis code updated
authorauras <antonio.uras@cern.ch>
Tue, 8 Apr 2014 22:24:16 +0000 (00:24 +0200)
committerauras <antonio.uras@cern.ch>
Tue, 8 Apr 2014 22:24:16 +0000 (00:24 +0200)
MFT/AliAnalysisTaskMFTExample.cxx
MFT/AliMFTAnalysisTools.cxx [new file with mode: 0644]
MFT/AliMFTAnalysisTools.h [new file with mode: 0644]
MFT/AliMFTConstants.h
MFT/AliMFTTrackerMU.cxx
MFT/CMakelibMFTbase.pkg
MFT/MFTbaseLinkDef.h

index 52e2cd6..5fab983 100755 (executable)
@@ -11,7 +11,7 @@
 #include "AliAODHeader.h"
 #include "TClonesArray.h"
 #include "AliMFTConstants.h"
-#include "AliMFTSupport.h"
+#include "AliMFTAnalysisTools.h"
 #include "TRandom.h"
 #include "TList.h"
 
@@ -209,14 +209,18 @@ void AliAnalysisTaskMFTExample::UserExec(Option_t *) {
        mcMuon2 = (AliAODMCParticle*) stackMC->At(recMuon2->GetLabel());
        if (mcMuon2) {
          if (mcMuon2->GetMother() == mcMuon1->GetMother()) {
-           Double_t vertex[3]={0};
+           Double_t pca[3]={0};
+           Double_t pcaQuality=0;
+           TClonesArray *muons = new TClonesArray("AliAODTrack",2);
+           muons -> Add(recMuon1);
+           muons -> Add(recMuon2);
            TLorentzVector kinem(0,0,0,0);
-           if (!AliMFTSupport::RefitAODDimuonWithCommonVertex(dimuon, vertex, kinem)) continue;
+           if (!AliMFTAnalysisTools::RefitAODDimuonWithCommonVertex(muons, pca, pcaQuality, kinem)) continue;
            fHistPtDimuonsJpsi    -> Fill(kinem.Pt());
            fHistMassDimuonsJpsi  -> Fill(kinem.M());
-           fHistResidualXVtxJpsi -> Fill(1.e4*(vertex[0] - fPrimaryVertex[0]));
-           fHistResidualYVtxJpsi -> Fill(1.e4*(vertex[1] - fPrimaryVertex[1]));
-           fHistResidualZVtxJpsi -> Fill(1.e4*(vertex[2] - fPrimaryVertex[2]));
+           fHistResidualXVtxJpsi -> Fill(1.e4*(pca[0] - fPrimaryVertex[0]));
+           fHistResidualYVtxJpsi -> Fill(1.e4*(pca[1] - fPrimaryVertex[1]));
+           fHistResidualZVtxJpsi -> Fill(1.e4*(pca[2] - fPrimaryVertex[2]));
          }
        }
       }
diff --git a/MFT/AliMFTAnalysisTools.cxx b/MFT/AliMFTAnalysisTools.cxx
new file mode 100644 (file)
index 0000000..1939159
--- /dev/null
@@ -0,0 +1,516 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Support class for various common operation on MFT objects
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliAODTrack.h"
+#include "AliAODDimuon.h"
+#include "TLorentzVector.h"
+#include "AliMFTConstants.h"
+#include "TDatabasePDG.h"
+#include "TMath.h"
+#include "AliLog.h"
+#include "TClonesArray.h"
+
+#include "AliMFTAnalysisTools.h"
+
+ClassImp(AliMFTAnalysisTools)
+
+//====================================================================================================================================================
+
+Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2]) {
+
+  if (!(muon->Pz()!=0)) return kFALSE;
+
+  AliMUONTrackParam *param = new AliMUONTrackParam();
+
+  param -> SetNonBendingCoor(muon->XAtDCA());
+  param -> SetBendingCoor(muon->YAtDCA());
+  param -> SetZ(AliMFTConstants::fZEvalKinem);
+  param -> SetNonBendingSlope(muon->Px()/muon->Pz());
+  param -> SetBendingSlope(muon->Py()/muon->Pz());
+  param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
+
+  AliMUONTrackExtrap::ExtrapToZ(param, z);
+  xy[0] = param->GetNonBendingCoor();
+  xy[1] = param->GetBendingCoor();
+
+  delete param;
+
+  return kTRUE;
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem) {
+
+  if (!(muon->Pz()!=0)) return kFALSE;
+
+  AliMUONTrackParam *param = new AliMUONTrackParam();
+
+  param -> SetNonBendingCoor(muon->XAtDCA());
+  param -> SetBendingCoor(muon->YAtDCA());
+  param -> SetZ(AliMFTConstants::fZEvalKinem);
+  param -> SetNonBendingSlope(muon->Px()/muon->Pz());
+  param -> SetBendingSlope(muon->Py()/muon->Pz());
+  param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
+
+  AliMUONTrackExtrap::ExtrapToZ(param, z);
+  xy[0] = param->GetNonBendingCoor();
+  xy[1] = param->GetBendingCoor();
+
+  Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
+  Double_t energy = TMath::Sqrt(massMu*massMu + param->Px()*param->Px() + param->Py()*param->Py() + param->Pz()*param->Pz());
+  
+  kinem.SetPxPyPzE(param->Px(), param->Py(), param->Pz(), energy);
+
+  delete param;
+
+  return kTRUE;
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTAnalysisTools::ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem, TMatrixD &cov) {
+
+  if (!(muon->Pz()!=0)) return kFALSE;
+
+  AliMUONTrackParam *param = new AliMUONTrackParam();
+
+  param -> SetNonBendingCoor(muon->XAtDCA());
+  param -> SetBendingCoor(muon->YAtDCA());
+  param -> SetZ(AliMFTConstants::fZEvalKinem);
+  param -> SetNonBendingSlope(muon->Px()/muon->Pz());
+  param -> SetBendingSlope(muon->Py()/muon->Pz());
+  param -> SetInverseBendingMomentum( muon->Charge() * (1./muon->Pz()) / (TMath::Sqrt(1+TMath::Power(muon->Py()/muon->Pz(),2))) );
+
+  param -> SetCovariances(ConvertCovMatrixAOD2MUON(muon));
+
+  AliMUONTrackExtrap::ExtrapToZCov(param, z);
+  xy[0] = param->GetNonBendingCoor();
+  xy[1] = param->GetBendingCoor();
+
+  Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
+  Double_t energy = TMath::Sqrt(massMu*massMu + param->Px()*param->Px() + param->Py()*param->Py() + param->Pz()*param->Pz());
+  
+  kinem.SetPxPyPzE(param->Px(), param->Py(), param->Pz(), energy);
+
+  cov = param->GetCovariances();
+
+  delete param;
+
+  return kTRUE;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMFTAnalysisTools::GetAODMuonOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv) {
+
+  Double_t xy[2] = {0};
+  ExtrapAODMuonToZ(muon, zv, xy);
+  
+  return TMath::Sqrt((xv-xy[0])*(xv-xy[0]) + (yv-xy[1])*(yv-xy[1]));
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMFTAnalysisTools::GetAODMuonWeightedOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv) {
+
+  Double_t xy[2] = {0};
+  TLorentzVector kinem(0,0,0,0);
+  TMatrixD cov(5,5);
+
+  ExtrapAODMuonToZ(muon, zv, xy, kinem, cov);
+
+  TMatrixD covCoordinates(2,2);
+  covCoordinates(0,0) = cov(0,0);
+  covCoordinates(0,1) = cov(0,2);
+  covCoordinates(1,0) = cov(2,0);
+  covCoordinates(1,1) = cov(2,2);
+  
+  TMatrixD covCoordinatesInverse = covCoordinates.Invert();
+
+  Double_t dX = xy[0] - xv;
+  Double_t dY = xy[1] - yv;
+  
+  Double_t weightedOffset = TMath::Sqrt(0.5*(dX*dX*covCoordinatesInverse(0,0) + 
+                                            dY*dY*covCoordinatesInverse(1,1) + 
+                                            2.*dX*dY*covCoordinatesInverse(0,1)));
+
+  return weightedOffset;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMFTAnalysisTools::GetPseudoProperDecayTimeXY(Double_t xVtx,  Double_t yVtx, 
+                                                        Double_t xDimu, Double_t yDimu, 
+                                                        Double_t mDimu, Double_t ptDimu) {
+  
+  // pseudo-proper decay time of a particle produced in the primary vertex and decaying into a dimuon (+ X)
+  // evaluated using the transverse degree of freedom of the decay topology 
+
+  if (ptDimu != 0) {
+    Double_t decayLengthXY = TMath::Sqrt((xVtx-xDimu)*(xVtx-xDimu)+(yVtx-yDimu)*(yVtx-yDimu));
+    return (decayLengthXY * mDimu/ptDimu)/TMath::Ccgs()*1E12;   // in ps
+  }
+  
+  return -99999999;
+  
+}
+
+//====================================================================================================================================================
+
+Double_t AliMFTAnalysisTools::GetPseudoProperDecayTimeZ(Double_t zVtx, 
+                                                       Double_t zDimu, 
+                                                       Double_t mDimu, Double_t pzDimu) {
+
+  // pseudo-proper decay time of a particle produced in the primary vertex and decaying into a dimuon (+ X)
+  // evaluated using the longitudinal degree of freedom of the decay topology 
+
+  if (pzDimu != 0) {
+    Double_t decayLengthZ = zDimu - zVtx;
+    return (decayLengthZ * mDimu/pzDimu)/TMath::Ccgs()*1E12;  // in ps
+  }
+
+  return -99999999;
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTAnalysisTools::CalculatePCA(TClonesArray *muons, Double_t *pca, Double_t &pcaQuality, TLorentzVector &kinem) {
+  
+  const Int_t nMuons = muons->GetEntriesFast();
+  if (nMuons<2 || nMuons>AliMFTConstants::fNMaxMuonsForPCA) {
+    printf("W-AliMFTAnalysisTools::CalculatePCA: number of muons not valid\n");
+    return kFALSE;
+  }
+  
+  Double_t fXPointOfClosestApproach=0, fYPointOfClosestApproach=0, fZPointOfClosestApproach=0;
+  
+  AliAODTrack *muon[nMuons];
+  AliMUONTrackParam *param[nMuons];
+
+  // Finding AliMUONTrackParam objects for each muon
+  
+  for (Int_t iMu=0; iMu<nMuons; iMu++) {
+    muon[iMu] = (AliAODTrack*) muons->At(iMu);
+    if (TMath::Abs(muon[iMu]->Pz())<1.e-6) return kFALSE;
+    param[iMu] = new AliMUONTrackParam();
+    param[iMu] -> SetNonBendingCoor(muon[iMu]->XAtDCA());
+    param[iMu] -> SetBendingCoor(muon[iMu]->YAtDCA());
+    param[iMu] -> SetZ(0.);
+    param[iMu] -> SetNonBendingSlope(muon[iMu]->Px()/muon[iMu]->Pz());
+    param[iMu] -> SetBendingSlope(muon[iMu]->Py()/muon[iMu]->Pz());
+    param[iMu] -> SetInverseBendingMomentum( muon[iMu]->Charge() * (1./muon[iMu]->Pz()) / (TMath::Sqrt(1+TMath::Power(muon[iMu]->Py()/muon[iMu]->Pz(),2))) );
+  }
+
+  // here we want to understand in which direction we have to search the minimum...
+  
+  Double_t step = 1.;  // initial step, in cm
+  Double_t startPoint = 0.;
+
+  Double_t r[3]={0}, z[3]={startPoint, startPoint+step, startPoint+2*step};
+  
+  TVector3 **points = new TVector3*[nMuons];
+  
+  for (Int_t i=0; i<3; i++) {
+    for (Int_t iMu=0; iMu<nMuons; iMu++) {
+      AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
+      points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
+    }
+    r[i] = GetDistanceBetweenPoints(points,nMuons);
+  }
+
+  Int_t researchDirection = 0;
+  
+  if      (r[0]>r[1] && r[1]>r[2]) researchDirection = +1;   // towards z positive
+  else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1;   // towards z negative
+  else if (r[0]<r[1] && r[1]>r[2]) {
+    printf("E-AliMFTAnalysisTools::CalculatePCA: Point of closest approach cannot be found for dimuon (no minima)\n");
+    return kFALSE;
+  }
+
+  while (TMath::Abs(researchDirection)>0.5) {
+
+    if (researchDirection>0) {
+      z[0] = z[1];
+      z[1] = z[2];
+      z[2] = z[1]+researchDirection*step;
+    }
+    else {
+      z[2] = z[1];
+      z[1] = z[0];
+      z[0] = z[1]+researchDirection*step;
+    }
+    if (TMath::Abs(z[0])>900.) {
+      printf("E-AliMFTAnalysisTools::CalculatePCA: Point of closest approach cannot be found for dimuon (no minima in the fiducial region)\n");
+      return kFALSE;
+    }
+    
+    for (Int_t iMu=0; iMu<nMuons; iMu++) delete points[iMu];
+    
+    for (Int_t i=0; i<3; i++) {
+      for (Int_t iMu=0; iMu<nMuons; iMu++) {
+        AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
+        points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
+      }      
+      r[i] = GetDistanceBetweenPoints(points,nMuons);
+    }
+    researchDirection=0;
+    if      (r[0]>r[1] && r[1]>r[2]) researchDirection = +1;   // towards z positive
+    else if (r[0]<r[1] && r[1]<r[2]) researchDirection = -1;   // towards z negative
+
+  }
+
+  // now we now that the minimum is between z[0] and z[2] and we search for it
+  
+  step *= 0.5;
+  while (step>AliMFTConstants::fPrecisionPointOfClosestApproach) {
+    z[0] = z[1]-step;
+    z[2] = z[1]+step;
+    for (Int_t i=0; i<3; i++) {
+      for (Int_t iMu=0; iMu<nMuons; iMu++) {
+        AliMUONTrackExtrap::ExtrapToZ(param[iMu], z[i]);
+        points[iMu] = new TVector3(param[iMu]->GetNonBendingCoor(),param[iMu]->GetBendingCoor(),z[i]);
+      }      
+      r[i] = GetDistanceBetweenPoints(points,nMuons);
+    }
+    if      (r[0]<r[1]) z[1] = z[0];
+    else if (r[2]<r[1]) z[1] = z[2];
+    else step *= 0.5;
+  }
+  
+  delete [] points;
+
+  // Once z of minimum is found, we evaluate the x and y coordinates by averaging over the contributing tracks
+  
+  fZPointOfClosestApproach = z[1];
+  fXPointOfClosestApproach = 0.;
+  fYPointOfClosestApproach = 0.;
+  for (Int_t iMu=0; iMu<nMuons; iMu++) {
+    AliMUONTrackExtrap::ExtrapToZ(param[iMu], fZPointOfClosestApproach);
+    fXPointOfClosestApproach += param[iMu]->GetNonBendingCoor();
+    fYPointOfClosestApproach += param[iMu]->GetBendingCoor();
+  }
+  fXPointOfClosestApproach /= Double_t(nMuons);
+  fYPointOfClosestApproach /= Double_t(nMuons);
+  
+  pca[0] = fXPointOfClosestApproach;
+  pca[1] = fYPointOfClosestApproach;
+  pca[2] = fZPointOfClosestApproach;
+  
+  // Evaluating the kinematics of the N-muon
+
+  Double_t pTot[3] = {0};
+  Double_t ene = 0.;
+  Double_t massMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
+  for (Int_t iMu=0; iMu<nMuons; iMu++) {
+    pTot[0] += param[iMu]->Px();
+    pTot[1] += param[iMu]->Py();
+    pTot[2] += param[iMu]->Pz();
+    ene += TMath::Sqrt(massMu*massMu + param[iMu]->Px()*param[iMu]->Px() + param[iMu]->Py()*param[iMu]->Py() + param[iMu]->Pz()*param[iMu]->Pz());
+  }
+  
+  kinem.SetPxPyPzE(pTot[0], pTot[1], pTot[2], ene);
+
+  // Evaluating the PCA quality of the N-muon
+
+  Double_t sum=0.,squareSum=0.;
+  for (Int_t iMu=0; iMu<nMuons; iMu++) {
+    Double_t wOffset = AliMFTAnalysisTools::GetAODMuonWeightedOffset(muon[iMu],fXPointOfClosestApproach, fYPointOfClosestApproach, fZPointOfClosestApproach);
+    Double_t f = TMath::Exp(-0.5 * wOffset);
+    sum += f;
+    squareSum += f*f;
+  }
+  if (sum > 0.) pcaQuality =  (sum-squareSum/sum) / (nMuons-1);
+  else pcaQuality = 0.;
+
+  return kTRUE;
+  
+}
+
+//=========================================================================================================================
+
+Double_t AliMFTAnalysisTools::GetDistanceBetweenPoints(TVector3 **points, Int_t nPoints) {
+  
+  if (nPoints>AliMFTConstants::fNMaxMuonsForPCA) {
+    printf("W-AliMFTAnalysisTools::GetDistanceBetweenPoints: number of points not valid\n");
+    return 1.e9;
+  }
+  
+  if (nPoints<2) return 0.;
+  if (nPoints<3) return TMath::Sqrt( (points[0]->X()-points[1]->X()) * (points[0]->X()-points[1]->X()) +
+                                    (points[0]->Y()-points[1]->Y()) * (points[0]->Y()-points[1]->Y()) +
+                                    (points[0]->Z()-points[1]->Z()) * (points[0]->Z()-points[1]->Z()) );
+
+  const Int_t nEdgesMax = ((AliMFTConstants::fNMaxMuonsForPCA) * (AliMFTConstants::fNMaxMuonsForPCA - 1)) / 2;
+  
+  Int_t startID[nEdgesMax]       = {0};
+  Int_t stopID[nEdgesMax]        = {0};
+  Double_t edgeLength[nEdgesMax] = {0};
+
+  Bool_t pointStatus[AliMFTConstants::fNMaxMuonsForPCA] = {0};
+  
+  Int_t nEdges=0;
+  for (Int_t i=0; i<nPoints-1; i++) {
+    for (Int_t j=i+1; j<nPoints; j++) {
+      edgeLength[nEdges] = TMath::Sqrt( (points[i]->X()-points[j]->X()) * (points[i]->X()-points[j]->X()) +
+                                        (points[i]->Y()-points[j]->Y()) * (points[i]->Y()-points[j]->Y()) +
+                                        (points[i]->Z()-points[j]->Z()) * (points[i]->Z()-points[j]->Z()) );
+      stopID[nEdges]  = i;
+      startID[nEdges] = j;
+      nEdges++;
+    }
+  }
+  // Order Edges
+
+  Double_t min = 0;
+  Int_t   iMin = 0;
+
+  for (Int_t iEdge=0; iEdge<nEdges-1; iEdge++) {
+    min  = edgeLength[iEdge];
+    iMin = iEdge;
+    for (Int_t j=iEdge+1; j<nEdges; j++) {
+      if (edgeLength[j]<min) {
+        min  = edgeLength[j];
+        iMin = j;
+      }
+    }
+    
+    if (iMin != iEdge) {
+
+      Double_t edgeLengthMin = edgeLength[iMin];
+      Int_t startIDmin = startID[iMin];
+      Int_t stopIDmin  = stopID[iMin];
+      
+      edgeLength[iMin] = edgeLength[iEdge];
+      startID[iMin]    = startID[iEdge];
+      stopID[iMin]     = stopID[iEdge];
+
+      edgeLength[iEdge] = edgeLengthMin;
+      startID[iEdge]    = startIDmin;
+      stopID[iEdge]     = stopIDmin;
+
+    }
+    
+  }
+  
+  // Connect
+
+  Double_t length = 0.;
+  for (Int_t i=0; i<nEdges; i++) {
+    if (!(pointStatus[startID[i]] && pointStatus[stopID[i]])) {
+      pointStatus[startID[i]] = kTRUE;
+      pointStatus[stopID[i]]  = kTRUE;
+      length += edgeLength[i];
+    }
+  }
+  
+  return length;
+  
+}
+
+//====================================================================================================================================================
+
+void AliMFTAnalysisTools::ConvertCovMatrixMUON2AOD(const TMatrixD& covMUON, Double_t covAOD[21]) {
+
+  // Converts the cov matrix from the MUON format (TMatrixD) to the AOD one (Double_t[21])
+  // 
+  // Cov(x,x)       ... :   cv[0]
+  // Cov(x,slopeX)  ... :   cv[1]  cv[2]
+  // Cov(x,y)       ... :   cv[3]  cv[4]  cv[5]
+  // Cov(x,slopeY)  ... :   cv[6]  cv[7]  cv[8]  cv[9]
+  // Cov(x,invP_yz) ... :   cv[10] cv[11] cv[12] cv[13] cv[14]
+  // not-used       ... :   cv[15] cv[16] cv[17] cv[18] cv[19] cv[20]
+
+  covAOD[0]  = covMUON(0,0);
+
+  covAOD[1]  = covMUON(1,0);
+  covAOD[2]  = covMUON(1,1);
+
+  covAOD[3]  = covMUON(2,0);  
+  covAOD[4]  = covMUON(2,1);  
+  covAOD[5]  = covMUON(2,2);  
+
+  covAOD[6]  = covMUON(3,0);  
+  covAOD[7]  = covMUON(3,1);  
+  covAOD[8]  = covMUON(3,2);  
+  covAOD[9]  = covMUON(3,3);  
+
+  covAOD[10] = covMUON(4,0);  
+  covAOD[11] = covMUON(4,1);  
+  covAOD[12] = covMUON(4,2);  
+  covAOD[13] = covMUON(4,3);  
+  covAOD[14] = covMUON(4,4);  
+
+  covAOD[15] = 0;  
+  covAOD[16] = 0;  
+  covAOD[17] = 0;  
+  covAOD[18] = 0;  
+  covAOD[19] = 0;  
+  covAOD[20] = 0;  
+
+}
+
+//====================================================================================================================================================
+
+const TMatrixD AliMFTAnalysisTools::ConvertCovMatrixAOD2MUON(AliAODTrack *muon) {
+
+  Double_t covAOD[21] = {0};
+  muon -> GetCovarianceXYZPxPyPz(covAOD);
+
+  TMatrixD covMUON(5,5);
+
+  covMUON(0,0) = covAOD[0];
+                               
+  covMUON(1,0) = covAOD[1];
+  covMUON(1,1) = covAOD[2];
+                               
+  covMUON(2,0) = covAOD[3];  
+  covMUON(2,1) = covAOD[4];  
+  covMUON(2,2) = covAOD[5];  
+                               
+  covMUON(3,0) = covAOD[6];  
+  covMUON(3,1) = covAOD[7];  
+  covMUON(3,2) = covAOD[8];  
+  covMUON(3,3) = covAOD[9];  
+                               
+  covMUON(4,0) = covAOD[10];  
+  covMUON(4,1) = covAOD[11];  
+  covMUON(4,2) = covAOD[12];  
+  covMUON(4,3) = covAOD[13];  
+  covMUON(4,4) = covAOD[14]; 
+
+  return covMUON;
+
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMFTAnalysisTools.h b/MFT/AliMFTAnalysisTools.h
new file mode 100644 (file)
index 0000000..c0517d9
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef AliMFTAnalysisTools_H
+#define AliMFTAnalysisTools_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Support class for various common operation on MFT objects
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TObject.h"
+#include "AliAODTrack.h"
+#include "AliAODDimuon.h"
+#include "TLorentzVector.h"
+#include "AliMFTConstants.h"
+#include "TDatabasePDG.h"
+#include "TMath.h"
+#include "AliLog.h"
+#include "TMatrixD.h"
+#include "TClonesArray.h"
+
+//====================================================================================================================================================
+
+class AliMFTAnalysisTools : public TObject {
+
+public:
+
+  AliMFTAnalysisTools() : TObject() {;}
+  virtual ~AliMFTAnalysisTools() {;}
+  
+  static Bool_t ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2]);
+  static Bool_t ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem);
+  static Bool_t ExtrapAODMuonToZ(AliAODTrack *muon, Double_t z, Double_t xy[2], TLorentzVector &kinem, TMatrixD &cov);
+
+  static Double_t GetAODMuonOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv);
+  static Double_t GetAODMuonWeightedOffset(AliAODTrack *muon, Double_t xv, Double_t yv, Double_t zv);
+
+  static Bool_t CalculatePCA(TClonesArray *muons, Double_t *pca, Double_t &pcaQuality, TLorentzVector &kinem);
+  static Double_t GetDistanceBetweenPoints(TVector3 **points, Int_t nPoints);
+
+  static Double_t GetPseudoProperDecayTimeXY(Double_t xVtx, Double_t yVtx, Double_t xDimu, Double_t yDimu, Double_t mDimu, Double_t ptDimu);
+  static Double_t GetPseudoProperDecayTimeZ(Double_t zVtx, Double_t zDimu, Double_t mDimu, Double_t pzDimu);
+
+  static Bool_t PlaneExists(AliAODTrack *muon, Int_t iPlane) { return muon->GetMFTClusterPattern() & (1<<iPlane); }
+
+  static Bool_t IsWrongCluster(AliAODTrack *muon, Int_t iPlane) { 
+    if (!PlaneExists(muon, iPlane)) return kFALSE;
+    else return !(muon->GetMFTClusterPattern() & (1<<(iPlane+AliMFTConstants::fNMaxPlanes)));
+  }
+
+  static void ConvertCovMatrixMUON2AOD(const TMatrixD& covMUON, Double_t covAOD[21]);
+  static const TMatrixD ConvertCovMatrixAOD2MUON(AliAODTrack *muon);
+  
+  ClassDef(AliMFTAnalysisTools,1)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
index 85f949e..e96553d 100644 (file)
@@ -57,12 +57,14 @@ public:
 
   static const Double_t fMisalignmentMagnitude;   // Expected misalignment magnitude (for MC, waiting for OCDB)
 
+  static const Int_t fNMaxMuonsForPCA = 10;
+
 protected:
 
   AliMFTConstants() : TObject() {}
   virtual ~AliMFTConstants(){}
 
-  ClassDef(AliMFTConstants, 2)    // MFT global constants 
+  ClassDef(AliMFTConstants, 3)    // MFT global constants 
 
 };
        
index 40554a2..1c4c567 100644 (file)
@@ -336,6 +336,7 @@ Int_t AliMFTTrackerMU::Clusters2Tracks(AliESDEvent *event) {
       myESDTrack -> SetFirstTrackingPoint(newTrack->GetMFTCluster(0)->GetX(), newTrack->GetMFTCluster(0)->GetY(), newTrack->GetMFTCluster(0)->GetZ());
       myESDTrack -> SetXYAtVertex(newTrack->GetOffsetX(0., AliMFTConstants::fZEvalKinem), newTrack->GetOffsetY(0., AliMFTConstants::fZEvalKinem));
       myESDTrack -> SetRAtAbsorberEnd(newTrack->GetRAtAbsorberEnd());
+      myESDTrack -> SetCovariances(newTrack->GetTrackParamAtMFTCluster(0)->GetCovariances());
       myESDTrack -> SetChi2MatchTrigger(esdTrack->GetChi2MatchTrigger());
       myESDTrack -> SetMuonClusterMap(esdTrack->GetMuonClusterMap());
       myESDTrack -> SetHitsPatternInTrigCh(esdTrack->GetHitsPatternInTrigCh());
index fdd36fb..ed16f9c 100644 (file)
@@ -25,7 +25,7 @@
 # SHLIBS - Shared Libraries and objects for linking (Executables only)           #
 #--------------------------------------------------------------------------------#
 
-set ( SRCS  AliMFTConstants.cxx AliMFTPlane.cxx AliMFTSegmentation.cxx AliMFTDigit.cxx AliMFTCluster.cxx AliMFTSupport.cxx )
+set ( SRCS  AliMFTConstants.cxx AliMFTPlane.cxx AliMFTSegmentation.cxx AliMFTDigit.cxx AliMFTCluster.cxx AliMFTAnalysisTools.cxx )
 
 string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
 
@@ -33,6 +33,8 @@ set ( DHDR MFTbaseLinkDef.h)
 
 set ( EINCLUDE  STRUCT RAW MUON STEER/STEER STEER/STEERBase)
 
+set ( EXPORT AliMFTAnalysisTools.h AliMFTConstants.h)
+
 if( ALICE_TARGET STREQUAL "win32gcc")
        
                set ( PACKSOFLAGS  ${SOFLAGS} -L${ALICE_ROOT}/lib/tgt_${ALICE_TARGET} -lSTEER -lCDB -lSTEERBase )
index c2f57db..6504e5e 100644 (file)
@@ -11,6 +11,6 @@
 #pragma link C++ class  AliMFTSegmentation+;
 #pragma link C++ class  AliMFTDigit+;
 #pragma link C++ class  AliMFTCluster+;
-#pragma link C++ class  AliMFTSupport+;
+#pragma link C++ class  AliMFTAnalysisTools+;
 
 #endif