Identify decay chains + new opt. (track selec., comb. label/pos. match, ...): added...
authorpcrochet <Philippe.Crochet@cern.ch>
Thu, 9 Oct 2014 10:36:04 +0000 (12:36 +0200)
committerpcrochet <Philippe.Crochet@cern.ch>
Thu, 9 Oct 2014 10:36:04 +0000 (12:36 +0200)
PWGPP/MUON/dep/AddTaskMuonFakes.C
PWGPP/MUON/dep/AliAnalysisTaskMuonFakes.cxx
PWGPP/MUON/dep/AliAnalysisTaskMuonFakes.h

index bd07511..9a1ac79 100644 (file)
@@ -1,4 +1,6 @@
-AliAnalysisTaskMuonFakes* AddTaskMuonFakes(Bool_t useMCLabels = kFALSE, Bool_t matchTrig = kFALSE, Bool_t applyAccCut = kFALSE)
+AliAnalysisTaskMuonFakes* AddTaskMuonFakes(Bool_t useMCLabels = kFALSE, Bool_t combineMCId = kFALSE,
+                                          Bool_t matchTrig = kFALSE, Bool_t applyAccCut = kFALSE,
+                                          TString extension = "")
 {
   /// Add AliAnalysisTaskMuonFakes to the train (Philippe Pillot)
   
@@ -17,12 +19,14 @@ AliAnalysisTaskMuonFakes* AddTaskMuonFakes(Bool_t useMCLabels = kFALSE, Bool_t m
   }
   
   // Create and configure task
-  AliAnalysisTaskMuonFakes *task = new AliAnalysisTaskMuonFakes("MUONFakes");
+  TString name = Form("MUONFakes%s",extension.Data());
+  AliAnalysisTaskMuonFakes *task = new AliAnalysisTaskMuonFakes(name.Data());
   if (!task) {
     Error("AddTaskMuonFakes", "Muon fakes task cannot be created!");
     return NULL;
   }
   task->UseMCLabels(useMCLabels);
+  task->CombineMCId(combineMCId);
   task->MatchTrigger(matchTrig);
   task->ApplyAccCut(applyAccCut);
   
@@ -39,15 +43,17 @@ AliAnalysisTaskMuonFakes* AddTaskMuonFakes(Bool_t useMCLabels = kFALSE, Bool_t m
     return NULL;
   }
   outputfile += ":MUON_Fakes";
+  TString suffix = (!extension.IsNull()) ? Form("_%s",extension.Data()) : "";
+  outputfile += suffix;
   
   // Create and connect output containers
-  AliAnalysisDataContainer *cout_histo = mgr->CreateContainer("histos", TObjArray::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_track = mgr->CreateContainer("trackCounters", AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_fakeTrack = mgr->CreateContainer("fakeTrackCounters", AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_matchTrack = mgr->CreateContainer("matchedTrackCounters", AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_event = mgr->CreateContainer("eventCounters", AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_histo2 = mgr->CreateContainer("histos2", TObjArray::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
-  AliAnalysisDataContainer *cout_pair = mgr->CreateContainer("pairCounters", AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_histo = mgr->CreateContainer(Form("histos%s",suffix.Data()), TObjArray::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_track = mgr->CreateContainer(Form("trackCounters%s",suffix.Data()), AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_fakeTrack = mgr->CreateContainer(Form("fakeTrackCounters%s",suffix.Data()), AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_matchTrack = mgr->CreateContainer(Form("matchedTrackCounters%s",suffix.Data()), AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_event = mgr->CreateContainer(Form("eventCounters%s",suffix.Data()), AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_histo2 = mgr->CreateContainer(Form("histos2%s",suffix.Data()), TObjArray::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
+  AliAnalysisDataContainer *cout_pair = mgr->CreateContainer(Form("pairCounters%s",suffix.Data()), AliCounterCollection::Class(), AliAnalysisManager::kOutputContainer, outputfile.Data());
   mgr->ConnectOutput(task, 1, cout_histo);
   mgr->ConnectOutput(task, 2, cout_track);
   mgr->ConnectOutput(task, 3, cout_fakeTrack);
index 3a8095d..60f1e6d 100644 (file)
@@ -21,6 +21,7 @@
 #include <TH1F.h>
 #include <TH2F.h>
 #include <TCanvas.h>
+#include <TArrayI.h>
 
 // STEER includes
 #include "AliLog.h"
@@ -30,6 +31,9 @@
 #include "AliMCEventHandler.h"
 #include "AliCDBManager.h"
 #include "AliCentrality.h"
+#include "AliMCParticle.h"
+#include "AliMCEvent.h"
+#include "AliCounterCollection.h"
 
 // ANALYSIS includes
 #include "AliAnalysisDataSlot.h"
@@ -46,9 +50,9 @@
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONESDInterface.h"
+#include "AliMUONTriggerTrack.h"
 
 #include "AliAnalysisTaskMuonFakes.h"
-#include "AliCounterCollection.h"
 
 ClassImp(AliAnalysisTaskMuonFakes)
 
@@ -67,10 +71,20 @@ fCurrentFileName(""),
 fRequestedStationMask(0),
 fRequest2ChInSameSt45(kFALSE),
 fSigmaCut(-1.),
+fNEvents(0),
+fShowProgressBar(kFALSE),
 fUseLabel(kFALSE),
+fCombineMCId(kFALSE),
+fExternalSigmaCut(-1.),
 fMatchTrig(kFALSE),
 fApplyAccCut(kFALSE),
-fRecoParamLocation("alien://folder=/alice/simulation/2008/v4-15-Release/Full")
+fChi2Cut(-1.),
+fPtCut(-1.),
+fRecoParamLocation(""),
+fDecayAsFake(kFALSE),
+fPrintDecayChain(kFALSE),
+fDisableDetailedCounters(kFALSE),
+fMuonTrackCuts(0x0)
 {
   /// Default constructor.
 }
@@ -90,10 +104,20 @@ fCurrentFileName(""),
 fRequestedStationMask(0),
 fRequest2ChInSameSt45(kFALSE),
 fSigmaCut(-1.),
+fNEvents(0),
+fShowProgressBar(kFALSE),
 fUseLabel(kFALSE),
+fCombineMCId(kFALSE),
+fExternalSigmaCut(-1.),
 fMatchTrig(kFALSE),
 fApplyAccCut(kFALSE),
-fRecoParamLocation("alien://folder=/alice/simulation/2008/v4-15-Release/Full")
+fChi2Cut(-1.),
+fPtCut(-1.),
+fRecoParamLocation("raw://"),
+fDecayAsFake(kFALSE),
+fPrintDecayChain(kFALSE),
+fDisableDetailedCounters(kFALSE),
+fMuonTrackCuts(0x0)
 {
   /// Constructor.
   // Output slot #1 writes into a TObjArray container
@@ -126,6 +150,7 @@ AliAnalysisTaskMuonFakes::~AliAnalysisTaskMuonFakes()
     delete fPairCounters;
   }
   delete fCanvases;
+  delete fMuonTrackCuts;
 }
 
 //___________________________________________________________________________
@@ -137,117 +162,113 @@ void AliAnalysisTaskMuonFakes::UserCreateOutputObjects()
   fList = new TObjArray(100);
   fList->SetOwner();
   
+  TH1F *h = 0x0;
+  TH2F *h2 = 0x0;
+  TString nameSuffix0[2] = {"", "S"};
+  TString nameSuffixT[6] = {"", "M", "MY", "D", "DY", "F"};
+  TString titlePrefix0[2] = {"", "selected "};
+  TString titlePrefixT[6] = {"", "matched ", "not reconstructible matched ", "decay ", "not reconstructible decay ", "fake "};
+  for (Int_t i = 0; i < 2; i++) {
+    
+    for (Int_t j = 0; j < 6; j++) {
+      
+      // number of clusters
+      h = new TH1F(Form("hNumberOfClusters%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("nb of clusters /%s%strack",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 21, -0.5, 20.5);
+      fList->AddAtAndExpand(h, kNumberOfClusters+i*kNhistTrack+j);
+      
+      // number of fired chambers
+      h = new TH1F(Form("hNumberOfChamberHit%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("nb of chambers hit /%s%strack",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 16, -0.5, 15.5);
+      fList->AddAtAndExpand(h, kNumberOfChamberHit+i*kNhistTrack+j);
+      
+      // chi2
+      h = new TH1F(Form("hChi2PerDof%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack chi2/d.o.f.",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 200, 0., 20.);
+      fList->AddAtAndExpand(h, kChi2PerDof+i*kNhistTrack+j);
+      
+      // chi2 versus number of clusters
+      h2 = new TH2F(Form("hChi2PerDofVsNClusters%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                   Form("%s%strack chi2/d.o.f. versus nb of clusters",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 21, -0.5, 20.5, 100, 0., 20.);
+      fList->AddAtAndExpand(h2, kChi2PerDofVsNClusters+i*kNhistTrack+j);
+      
+      // chi2 versus number of fired chambers
+      h2 = new TH2F(Form("hChi2PerDofVsNChamberHit%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                   Form("%s%strack chi2/d.o.f. versus nb of fired chambers",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 16, -0.5, 15.5, 100, 0., 20.);
+      fList->AddAtAndExpand(h2, kChi2PerDofVsNChamberHit+i*kNhistTrack+j);
+      
+      // physics quantities
+      h = new TH1F(Form("hP%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack P distribution (GeV/c)",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 100, 0., 200.);
+      fList->AddAtAndExpand(h, kP+i*kNhistTrack+j);
+      h = new TH1F(Form("hPt%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack Pt distribution (GeV/c)",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 100, 0., 20.);
+      fList->AddAtAndExpand(h, kPt+i*kNhistTrack+j);
+      h = new TH1F(Form("hEta%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack pseudo-rapidity distribution",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 200, -10., 0.);
+      fList->AddAtAndExpand(h , kEta+i*kNhistTrack+j);
+      h = new TH1F(Form("hPhi%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack phi distribution",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 100, -1., 9.);
+      fList->AddAtAndExpand(h, kPhi+i*kNhistTrack+j);
+      h = new TH1F(Form("hDCA%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack DCA distribution",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 250, 0., 500.);
+      fList->AddAtAndExpand(h, kDCA+i*kNhistTrack+j);
+      h = new TH1F(Form("hPDCA23%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack P*DCA distribution in 2-3 deg",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 250, 0., 5000.);
+      fList->AddAtAndExpand(h, kPDCA23+i*kNhistTrack+j);
+      h = new TH1F(Form("hPDCA310%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack P*DCA distribution in 3-10 deg",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 250, 0., 5000.);
+      fList->AddAtAndExpand(h, kPDCA310+i*kNhistTrack+j);
+      h = new TH1F(Form("hRAbs%s%s",nameSuffix0[i].Data(),nameSuffixT[j].Data()),
+                  Form("%s%strack R_{Abs} distribution",titlePrefix0[i].Data(),titlePrefixT[j].Data()), 200, 0., 100.);
+      fList->AddAtAndExpand(h, kRAbs+i*kNhistTrack+j);
+      
+    }
+    
+  }
+  
   // number of tracks
   TH1F *hNumberOfTracks = new TH1F("hNumberOfTracks", "nb of tracks /evt", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfTracks, kNumberOfTracks);
+  fList->AddAtAndExpand(hNumberOfTracks, 2*kNhistTrack+kNumberOfTracks);
   TH1F *hNumberOfAdditionalTracks = new TH1F("hNumberOfAdditionalTracks", "nb of fake - nb of missing track", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfAdditionalTracks, kNumberOfAdditionalTracks);
-  
-  // number of clusters
-  TH1F *hNumberOfClusters = new TH1F("hNumberOfClusters", "nb of clusters /track", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfClusters, kNumberOfClusters);
-  TH1F *hNumberOfClustersM = new TH1F("hNumberOfClustersM", "nb of clusters /matched track", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfClustersM, kNumberOfClustersM);
-  TH1F *hNumberOfClustersF = new TH1F("hNumberOfClustersF", "nb of clusters /fake track", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfClustersF, kNumberOfClustersF);
+  fList->AddAtAndExpand(hNumberOfAdditionalTracks, 2*kNhistTrack+kNumberOfAdditionalTracks);
+  
+  // number of clusters MC / fraction of clusters
   TH1F *hNumberOfClustersMC = new TH1F("hNumberOfClustersMC", "nb of clusters /MC track", 21, -0.5, 20.5);
-  fList->AddAtAndExpand(hNumberOfClustersMC, kNumberOfClustersMC);
+  fList->AddAtAndExpand(hNumberOfClustersMC, 2*kNhistTrack+kNumberOfClustersMC);
   TH1F *hFractionOfMatchedClusters = new TH1F("hFractionOfMatchedClusters", "nb of matched clusters / nb of clusters", 110, 0., 1.1);
-  fList->AddAtAndExpand(hFractionOfMatchedClusters, kFractionOfMatchedClusters);
+  fList->AddAtAndExpand(hFractionOfMatchedClusters, 2*kNhistTrack+kFractionOfMatchedClusters);
   TH1F *hFractionOfConnectedClusters = new TH1F("hFractionOfConnectedClusters", "nb of connected clusters / nb of clusters in fake tracks", 110, 0., 1.1);
-  fList->AddAtAndExpand(hFractionOfConnectedClusters, kFractionOfConnectedClusters);
-  
-  // number of fired chambers
-  TH1F *hNumberOfChamberHit = new TH1F("hNumberOfChamberHit", "nb of chambers hit /track", 16, -0.5, 15.5);
-  fList->AddAtAndExpand(hNumberOfChamberHit, kNumberOfChamberHit);
-  TH1F *hNumberOfChamberHitM = new TH1F("hNumberOfChamberHitM", "nb of chambers hit /matched track", 16, -0.5, 15.5);
-  fList->AddAtAndExpand(hNumberOfChamberHitM, kNumberOfChamberHitM);
-  TH1F *hNumberOfChamberHitF = new TH1F("hNumberOfChamberHitF", "nb of chambers hit /fake track", 16, -0.5, 15.5);
-  fList->AddAtAndExpand(hNumberOfChamberHitF, kNumberOfChamberHitF);
-  
-  // chi2
-  TH1F *hChi2PerDof = new TH1F("hChi2PerDof", "track chi2/d.o.f.", 200, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDof, kChi2PerDof);
-  TH1F *hChi2PerDofM = new TH1F("hChi2PerDofM", "matched track chi2/d.o.f.", 200, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofM, kChi2PerDofM);
-  TH1F *hChi2PerDofF = new TH1F("hChi2PerDofF", "fake track chi2/d.o.f.", 200, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofF, kChi2PerDofF);
-  
-  // chi2 versus number of clusters
-  TH2F *hChi2PerDofVsNClusters = new TH2F("hChi2PerDofVsNClusters", "track chi2/d.o.f. versus nb of clusters", 21, -0.5, 20.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNClusters, kChi2PerDofVsNClusters);
-  TH2F *hChi2PerDofVsNClustersM = new TH2F("hChi2PerDofVsNClustersM", "matched track chi2/d.o.f. versus nb of clusters", 21, -0.5, 20.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNClustersM, kChi2PerDofVsNClustersM);
-  TH2F *hChi2PerDofVsNClustersF = new TH2F("hChi2PerDofVsNClustersF", "fake track chi2/d.o.f. versus nb of clusters", 21, -0.5, 20.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNClustersF, kChi2PerDofVsNClustersF);
-  
-  // chi2 versus number of fired chambers
-  TH2F *hChi2PerDofVsNChamberHit = new TH2F("hChi2PerDofVsNChamberHit", "track chi2/d.o.f. versus nb of fired chambers", 16, -0.5, 15.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNChamberHit, kChi2PerDofVsNChamberHit);
-  TH2F *hChi2PerDofVsNChamberHitM = new TH2F("hChi2PerDofVsNChamberHitM", "matched track chi2/d.o.f. versus nb of fired chambers", 16, -0.5, 15.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNChamberHitM, kChi2PerDofVsNChamberHitM);
-  TH2F *hChi2PerDofVsNChamberHitF = new TH2F("hChi2PerDofVsNChamberHitF", "fake track chi2/d.o.f. versus nb of fired chambers", 16, -0.5, 15.5, 100, 0., 20.);
-  fList->AddAtAndExpand(hChi2PerDofVsNChamberHitF, kChi2PerDofVsNChamberHitF);
-  
-  // physics quantities
-  TH1F *hP = new TH1F("hP", "Muon P distribution (GeV/c)", 100, 0., 200.);
-  fList->AddAtAndExpand(hP, kP);
-  TH1F *hPM = new TH1F("hPM", "matched track P distribution (GeV/c)", 100, 0., 200.);
-  fList->AddAtAndExpand(hPM, kPM);
-  TH1F *hPF = new TH1F("hPF", "fake track P distribution (GeV/c)", 100, 0., 200.);
-  fList->AddAtAndExpand(hPF, kPF);
-  TH1F *hPt = new TH1F("hPt", "Muon Pt distribution (GeV/c)", 100, 0., 20.);
-  fList->AddAtAndExpand(hPt, kPt);
-  TH1F *hPtM = new TH1F("hPtM", "matched track Pt distribution (GeV/c)", 100, 0., 20.);
-  fList->AddAtAndExpand(hPtM, kPtM);
-  TH1F *hPtF = new TH1F("hPtF", "fake track Pt distribution (GeV/c)", 100, 0., 20.);
-  fList->AddAtAndExpand(hPtF, kPtF);
-  TH1F *hEta = new TH1F("hEta", "Muon pseudo-rapidity distribution", 200, -10., 0.);
-  fList->AddAtAndExpand(hEta , kEta );
-  TH1F *hEtaM = new TH1F("hEtaM", "matched track pseudo-rapidity distribution", 200, -10., 0.);
-  fList->AddAtAndExpand(hEtaM, kEtaM);
-  TH1F *hEtaF = new TH1F("hEtaF", "fake track pseudo-rapidity distribution", 200, -10., 0.);
-  fList->AddAtAndExpand(hEtaF, kEtaF);
-  TH1F *hPhi = new TH1F("hPhi", "Muon phi distribution", 100, -1., 9.);
-  fList->AddAtAndExpand(hPhi, kPhi);
-  TH1F *hPhiM = new TH1F("hPhiM", "matched track phi distribution", 100, -1., 9.);
-  fList->AddAtAndExpand(hPhiM, kPhiM);
-  TH1F *hPhiF = new TH1F("hPhiF", "fake track phi distribution", 100, -1., 9.);
-  fList->AddAtAndExpand(hPhiF, kPhiF);
-  TH1F *hDCA = new TH1F("hDCA", "Muon DCA distribution", 250, 0., 500.);
-  fList->AddAtAndExpand(hDCA, kDCA);
-  TH1F *hDCAM = new TH1F("hDCAM", "matched track DCA distribution", 250, 0., 500.);
-  fList->AddAtAndExpand(hDCAM, kDCAM);
-  TH1F *hDCAF = new TH1F("hDCAF", "fake track DCA distribution", 250, 0., 500.);
-  fList->AddAtAndExpand(hDCAF, kDCAF);
-  TH1F *hRAbs = new TH1F("hRAbs", "Muon R_{Abs} distribution", 200, 0., 100.);
-  fList->AddAtAndExpand(hRAbs, kRAbs);
-  TH1F *hRAbsM = new TH1F("hRAbsM", "matched track R_{Abs} distribution", 300, 0., 150.);
-  fList->AddAtAndExpand(hRAbsM, kRAbsM);
-  TH1F *hRAbsF = new TH1F("hRAbsF", "fake track R_{Abs} distribution", 200, 0., 100.);
-  fList->AddAtAndExpand(hRAbsF, kRAbsF);
+  fList->AddAtAndExpand(hFractionOfConnectedClusters, 2*kNhistTrack+kFractionOfConnectedClusters);
   
   // track pair histograms
   fList2 = new TObjArray(100);
   fList2->SetOwner();
   
   // physics quantities of opposite-sign track pairs
-  TH1F* h = 0x0;
   TString nameSuffix[4] = {"", "M", "F1", "F2"};
-  TString titlePrefix[4] = {"Dimuon", "matched-matched pair", "matched-fake pair", "fake-fake pair"};
-  for (Int_t i = 0; i < 4; i++) {
-    h = new TH1F(Form("h2Mass%s",nameSuffix[i].Data()), Form("%s mass distribution (GeV/c^{2})",titlePrefix[i].Data()), 300, 0., 15.);
-    fList2->AddAtAndExpand(h, k2Mass+i);
-    h = new TH1F(Form("h2P%s",nameSuffix[i].Data()), Form("%s P distribution (GeV/c)",titlePrefix[i].Data()), 100, 0., 200.);
-    fList2->AddAtAndExpand(h, k2P+i);
-    h = new TH1F(Form("h2Pt%s",nameSuffix[i].Data()), Form("%s Pt distribution (GeV/c)",titlePrefix[i].Data()), 100, 0., 20.);
-    fList2->AddAtAndExpand(h, k2Pt+i);
-    h = new TH1F(Form("h2Y%s",nameSuffix[i].Data()), Form("%s rapidity distribution",titlePrefix[i].Data()), 200, -10., 0.);
-    fList2->AddAtAndExpand(h, k2Y+i);
-    h = new TH1F(Form("h2Eta%s",nameSuffix[i].Data()), Form("%s pseudo-rapidity distribution",titlePrefix[i].Data()), 200, -10., 0.);
-    fList2->AddAtAndExpand(h, k2Eta+i);
-    h = new TH1F(Form("h2Phi%s",nameSuffix[i].Data()), Form("%s phi distribution",titlePrefix[i].Data()), 100, -1., 9.);
-    fList2->AddAtAndExpand(h, k2Phi+i);
+  TString titlePrefix[4] = {"dimuon ", "matched-matched pair ", "matched-fake pair ", "fake-fake pair "};
+  for (Int_t i = 0; i < 2; i++) {
+    for (Int_t j = 0; j < 4; j++) {
+      h = new TH1F(Form("h2Mass%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%smass distribution (GeV/c^{2})",titlePrefix0[i].Data(),titlePrefix[j].Data()), 300, 0., 15.);
+      fList2->AddAtAndExpand(h, k2Mass+i*kNhistPair+j);
+      h = new TH1F(Form("h2P%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%sP distribution (GeV/c)",titlePrefix0[i].Data(),titlePrefix[j].Data()), 100, 0., 200.);
+      fList2->AddAtAndExpand(h, k2P+i*kNhistPair+j);
+      h = new TH1F(Form("h2Pt%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%sPt distribution (GeV/c)",titlePrefix0[i].Data(),titlePrefix[j].Data()), 100, 0., 20.);
+      fList2->AddAtAndExpand(h, k2Pt+i*kNhistPair+j);
+      h = new TH1F(Form("h2Y%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%srapidity distribution",titlePrefix0[i].Data(),titlePrefix[j].Data()), 200, -10., 0.);
+      fList2->AddAtAndExpand(h, k2Y+i*kNhistPair+j);
+      h = new TH1F(Form("h2Eta%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%spseudo-rapidity distribution",titlePrefix0[i].Data(),titlePrefix[j].Data()), 200, -10., 0.);
+      fList2->AddAtAndExpand(h, k2Eta+i*kNhistPair+j);
+      h = new TH1F(Form("h2Phi%s%s",nameSuffix0[i].Data(),nameSuffix[j].Data()),
+                  Form("%s%sphi distribution",titlePrefix0[i].Data(),titlePrefix[j].Data()), 100, -1., 9.);
+      fList2->AddAtAndExpand(h, k2Phi+i*kNhistPair+j);
+    }
   }
   
   // global counters of tracks:
@@ -255,11 +276,13 @@ void AliAnalysisTaskMuonFakes::UserCreateOutputObjects()
   // - reconstructed   = number of reconstructed tracks
   // - matched         = number of reconstructed tracks matched with a simulated one (reconstructible or not)
   // - matchedyet      = number of reconstructed tracks matched with a simulated one that is not reconstructible
+  // - decay           = number of reconstructed tracks matched with a decay chain (reconstructible or not)
+  // - decayyet        = number of reconstructed tracks matched with a decay chain that is not reconstructible
   // - fake            = number of fake tracks
   // - connected       = number of fake tracks connected to a reconstructible simulated track
   // - additional      = number of additional (fake) tracks compared to the number of reconstructible ones
   fTrackCounters = new AliCounterCollection(GetOutputSlot(2)->GetContainer()->GetName());
-  fTrackCounters->AddRubric("track", "reconstructible/reconstructed/matched/matchedyet/fake/connected/additional");
+  fTrackCounters->AddRubric("track", "reconstructible/reconstructed/matched/matchedyet/decay/decayyet/fake/connected/additional");
   fTrackCounters->AddRubric("run", 1000000);
   fTrackCounters->AddRubric("trig", "yes/no/unknown");
   fTrackCounters->AddRubric("selected", "yes/no");
@@ -268,9 +291,10 @@ void AliAnalysisTaskMuonFakes::UserCreateOutputObjects()
   fTrackCounters->AddRubric("cent", centralityClasses.Data());
   fTrackCounters->Init();
   
-  // detailled counters of fake tracks:
+  // detailled counters of decays and fake tracks:
   fFakeTrackCounters = new AliCounterCollection(GetOutputSlot(3)->GetContainer()->GetName());
-  fFakeTrackCounters->AddRubric("track", "fake/connected/additional/matchedyet/fake?");
+  fFakeTrackCounters->AddRubric("position", "matched/decay/decayyet/matchedyet/fake/connected/additional");
+  fFakeTrackCounters->AddRubric("label", "matched/decay/decayyet/matchedyet/fake/connected/additional");
   fFakeTrackCounters->AddRubric("run", 1000000);
   fFakeTrackCounters->AddRubric("file", 1000000);
   fFakeTrackCounters->AddRubric("event", 1000000);
@@ -282,8 +306,8 @@ void AliAnalysisTaskMuonFakes::UserCreateOutputObjects()
   
   // counters of tracks matched by position or by using MC labels
   fMatchedTrackCounters = new AliCounterCollection(GetOutputSlot(4)->GetContainer()->GetName());
-  fMatchedTrackCounters->AddRubric("position", "match/not match");
-  fMatchedTrackCounters->AddRubric("label", "match/not match/match other");
+  fMatchedTrackCounters->AddRubric("position", "matched/decay/decayyet/matchedyet/fake");
+  fMatchedTrackCounters->AddRubric("label", "matched/decay/decayyet/matchedyet/fake/matchedother");
   fMatchedTrackCounters->AddRubric("run", 1000000);
   fMatchedTrackCounters->AddRubric("trig", "yes/no");
   fMatchedTrackCounters->AddRubric("selected", "yes/no");
@@ -342,14 +366,19 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
   // check that reconstructions parameters for that run have been properly set
   if (fSigmaCut < 0) return;
   
+  if (fShowProgressBar && (++fNEvents)%100 == 0) cout<<"\rEvent processing... "<<fNEvents<<"\r"<<flush;
+  
   // check physics selection
   TString selected = (fInputHandler && fInputHandler->IsEventSelected() != 0) ? "selected:yes" : "selected:no";
   
   // current file name
-  fCurrentFileName = CurrentFileName();
-  fCurrentFileName.ReplaceAll("alien://","");
-  fCurrentFileName.ReplaceAll("/","\\");
-  fCurrentFileName.ReplaceAll(":",";");
+  if (fDisableDetailedCounters) fCurrentFileName = "any";
+  else {
+    fCurrentFileName = CurrentFileName();
+    fCurrentFileName.ReplaceAll("alien://","");
+    fCurrentFileName.ReplaceAll("/","\\");
+    fCurrentFileName.ReplaceAll(":",";");
+  }
   
   // Load ESD event
   AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
@@ -358,6 +387,9 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
     return;
   }      
   
+  // event number in current file
+  TString eventNumberInFile = (fDisableDetailedCounters) ? "event:any" : Form("event:%d",esd->GetEventNumberInFile());
+  
   // current centrality class
   TString centrality = "cent:";
   Double_t centralityValue = esd->GetCentrality()->GetCentralityPercentile("V0M");
@@ -395,7 +427,8 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
     if (!trackRef->IsValid(fRequestedStationMask, fRequest2ChInSameSt45)) continue;
     
     // trigger condition
-    Bool_t trigger = (triggerTrackRefStore->FindObject(trackRef->GetUniqueID()));
+    AliMUONTriggerTrack *trigRef = static_cast<AliMUONTriggerTrack*>(triggerTrackRefStore->FindObject(trackRef->GetUniqueID()));
+    Bool_t trigger = (trigRef && trigRef->GetPtCutLevel() > 0);
     Int_t iTrig = trigger ? 1 : 0;
     TString trig = trigger ? "trig:yes" : "trig:no";
     
@@ -418,14 +451,16 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
   Bool_t containTrack[2] = {kFALSE, kFALSE};
   Bool_t containFakeTrack[2] = {kFALSE, kFALSE};
   Bool_t containMatchedYetTrack[2] = {kFALSE, kFALSE};
+  AliMUONVTrackStore *usedTrackRefStore = AliMUONESDInterface::NewTrackStore();
   AliMUONVTrackStore *fakeTrackStore = AliMUONESDInterface::NewTrackStore();
-  Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks() ;
+  Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks();
+  TArrayI mcLabels(nTracks);
   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
     
     AliESDMuonTrack* esdTrack = esd->GetMuonTrack(iTrack);
     
     // skip ghosts
-    if (!esdTrack->ContainTrackerData()) continue;
+    if (!IsSelected(*esdTrack)) continue;
     containTrack[0] = kTRUE;
     
     // trigger condition
@@ -456,123 +491,222 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
     Double_t pT = esdTrack->Pt();
     Double_t phi = esdTrack->Phi();
     Double_t dca = esdTrack->GetDCA();
+    Double_t pU = esdTrack->PUncorrected();
+    Double_t pdca = 0.5*(p+pU)*dca;
     
     // fill global histograms
-    if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) {
-      ((TH1F*)fList->UncheckedAt(kNumberOfClusters))->Fill(nClusters);
-      ((TH1F*)fList->UncheckedAt(kNumberOfChamberHit))->Fill(nChamberHit);
-      ((TH1F*)fList->UncheckedAt(kChi2PerDof))->Fill(normalizedChi2);
-      ((TH1F*)fList->UncheckedAt(kP))->Fill(p);
-      ((TH1F*)fList->UncheckedAt(kPt))->Fill(pT);
-      ((TH1F*)fList->UncheckedAt(kEta))->Fill(eta);
-      ((TH1F*)fList->UncheckedAt(kPhi))->Fill(phi);
-      ((TH1F*)fList->UncheckedAt(kDCA))->Fill(dca);
-      ((TH1F*)fList->UncheckedAt(kRAbs))->Fill(rAbs);
-      ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNClusters))->Fill(nClusters,normalizedChi2);
-      ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNChamberHit))->Fill(nChamberHit,normalizedChi2);
-    }
+    FillHistoTrack(0, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+    if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc))
+      FillHistoTrack(kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
     
     // try to match, by position, the reconstructed track with a simulated one
     Int_t nMatchClustersByPosition = 0;
     AliMUONTrack* matchedTrackRefByPosition = rc.FindCompatibleTrack(*muonTrack, *trackRefStore, nMatchClustersByPosition, kFALSE, fSigmaCut);
-    Int_t MCLabelByPosition = (matchedTrackRefByPosition) ? static_cast<Int_t>(matchedTrackRefByPosition->GetUniqueID()) : -1;
+    Bool_t isMatchedYetByPosition = kFALSE;
+    Bool_t isRecoDecayByPosition = kFALSE;
+    Int_t decayLabelByPosition = -1, lastChDecayByPosition = 0;
+    if (!matchedTrackRefByPosition || !matchedTrackRefByPosition->IsValid(fRequestedStationMask, fRequest2ChInSameSt45)) {
+      decayLabelByPosition = IsDecayByPosition(*muonTrack, *trackRefStore, *usedTrackRefStore, isRecoDecayByPosition, lastChDecayByPosition);
+      if (decayLabelByPosition >= 0) matchedTrackRefByPosition = 0x0;
+      else if (matchedTrackRefByPosition) isMatchedYetByPosition = kTRUE;
+    }
+    Bool_t isFakeByPosition = (!matchedTrackRefByPosition && decayLabelByPosition < 0);
     
     // try to match, by using MC labels, the reconstructed track with a simulated one
     Int_t nMatchClustersByLabel = 0;
     AliMUONTrack* matchedTrackRefByLabel = rc.FindCompatibleTrack(*muonTrack, *trackRefStore, nMatchClustersByLabel, kTRUE, fSigmaCut);
-    Int_t MCLabelByLabel = (matchedTrackRefByLabel) ? static_cast<Int_t>(matchedTrackRefByLabel->GetUniqueID()) : -1;
+    Bool_t isMatchedYetByLabel = kFALSE;
+    Bool_t isRecoDecayByLabel = kFALSE;
+    Int_t decayLabelByLabel = -1, lastChDecayByLabel = 0;
+    if (!matchedTrackRefByLabel || !matchedTrackRefByLabel->IsValid(fRequestedStationMask, fRequest2ChInSameSt45)) {
+      decayLabelByLabel = IsDecayByLabel(*muonTrack, isRecoDecayByLabel, lastChDecayByLabel);
+      if (decayLabelByLabel >= 0) matchedTrackRefByLabel = 0x0;
+      else if (matchedTrackRefByLabel) isMatchedYetByLabel = kTRUE;
+    }
+    Bool_t isFakeByLabel = (!matchedTrackRefByLabel && decayLabelByLabel < 0);
     
     // fill global counters
-    TString positionCase = (MCLabelByPosition >= 0) ? "position:match" : "position:not match";
+    TString positionCase = "position:";
+    if (isMatchedYetByPosition) positionCase += "matchedyet";
+    else if (isRecoDecayByPosition) positionCase += "decay";
+    else if (decayLabelByPosition >= 0) positionCase += "decayyet";
+    else if (isFakeByPosition) positionCase += "fake";
+    else positionCase += "matched";
     TString labelCase = "label:";
-    if (MCLabelByLabel >= 0 && MCLabelByPosition >= 0 && MCLabelByLabel != MCLabelByPosition) labelCase += "match other";
-    else if (MCLabelByLabel >= 0) labelCase += "match";
-    else labelCase += "not match";
-    fMatchedTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/%s", positionCase.Data(), labelCase.Data(), fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-    if ((MCLabelByLabel >= 0 && MCLabelByPosition < 0) || (MCLabelByLabel < 0 && MCLabelByPosition >= 0))
-      fFakeTrackCounters->Count(Form("track:fake?/run:%d/file:%s/event:%d/%s/%s/%s/%s", fCurrentRunNumber, fCurrentFileName.Data(),
-                                    esd->GetEventNumberInFile(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-
+    if (isMatchedYetByLabel) labelCase += "matchedyet";
+    else if (isRecoDecayByLabel) labelCase += "decay";
+    else if (decayLabelByLabel >= 0) labelCase += "decayyet";
+    else if (isFakeByLabel) labelCase += "fake";
+    else labelCase += "matched";
+    if (!matchedTrackRefByPosition || isMatchedYetByPosition || !matchedTrackRefByLabel || isMatchedYetByLabel)
+      fFakeTrackCounters->Count(Form("%s/%s/run:%d/file:%s/%s/%s/%s/%s/%s", positionCase.Data(), labelCase.Data(), fCurrentRunNumber,
+                                    fCurrentFileName.Data(), eventNumberInFile.Data(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+    if (matchedTrackRefByLabel && matchedTrackRefByPosition &&
+       matchedTrackRefByLabel->GetUniqueID() != matchedTrackRefByPosition->GetUniqueID()) labelCase = "label:matchedother";
+    fMatchedTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/%s", positionCase.Data(), labelCase.Data(),
+                                     fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+    
     // take actions according to the matching result we are interested in
-    Int_t nMatchClusters = (fUseLabel) ? nMatchClustersByLabel : nMatchClustersByPosition;
-    AliMUONTrack* matchedTrackRef = (fUseLabel) ? matchedTrackRefByLabel : matchedTrackRefByPosition;
+    Int_t nMatchClusters = 0;
+    AliMUONTrack* matchedTrackRef = 0x0;
+    Bool_t isFake = kFALSE, isMatchedYet = kFALSE, isRecoDecay = kFALSE;
+    Int_t decayLabel = -1;
+    if (fCombineMCId) {
+      
+      // choose the best, or the only available, matched track
+      if (matchedTrackRefByPosition && matchedTrackRefByLabel && ((!isMatchedYetByPosition && !isMatchedYetByLabel) ||
+                                                                 (isMatchedYetByPosition && isMatchedYetByLabel))) {
+       
+       nMatchClusters = TMath::Max(nMatchClustersByPosition, nMatchClustersByLabel);
+       matchedTrackRef = (nMatchClusters == nMatchClustersByPosition) ? matchedTrackRefByPosition : matchedTrackRefByLabel;
+       isMatchedYet = isMatchedYetByPosition;
+       
+      } else if (matchedTrackRefByPosition && (!isMatchedYetByPosition || isFakeByLabel)) {
+       
+       nMatchClusters = nMatchClustersByPosition;
+       matchedTrackRef = matchedTrackRefByPosition;
+       isMatchedYet = isMatchedYetByPosition;
+       
+      } else if (matchedTrackRefByLabel && (!isMatchedYetByLabel || isFakeByPosition)) {
+       
+       nMatchClusters = nMatchClustersByLabel;
+       matchedTrackRef = matchedTrackRefByLabel;
+       isMatchedYet = isMatchedYetByLabel;
+       
+       // choose the best (even if it does not matter here), or the only available, decay chain
+      } else if (decayLabelByPosition >= 0 && decayLabelByLabel >= 0 && ((isRecoDecayByPosition && isRecoDecayByLabel) ||
+                                                                        (!isRecoDecayByPosition && !isRecoDecayByLabel))) {
+       
+       decayLabel = (lastChDecayByLabel > lastChDecayByPosition) ? decayLabelByLabel : decayLabelByPosition;
+       isRecoDecay = isRecoDecayByPosition;
+       
+      } else if (decayLabelByPosition >= 0 && (isRecoDecayByPosition || decayLabelByLabel < 0)) {
+       
+       decayLabel = decayLabelByPosition;
+       isRecoDecay = isRecoDecayByPosition;
+       
+      } else if (decayLabelByLabel >= 0) {
+       
+       decayLabel = decayLabelByLabel;
+       isRecoDecay = isRecoDecayByLabel;
+       
+       // no matched track and no decay chain... It must be fakes!
+      } else isFake = kTRUE;
+      
+    } else if (fUseLabel) {
+      
+      // choose the track matched by MC labels
+      nMatchClusters = nMatchClustersByLabel;
+      matchedTrackRef = matchedTrackRefByLabel;
+      isMatchedYet = isMatchedYetByLabel;
+      decayLabel = decayLabelByLabel;
+      isRecoDecay = isRecoDecayByLabel;
+      isFake = isFakeByLabel;
+      
+    } else {
+      
+      // choose the track matched by position
+      nMatchClusters = nMatchClustersByPosition;
+      matchedTrackRef = matchedTrackRefByPosition;
+      isMatchedYet = isMatchedYetByPosition;
+      decayLabel = decayLabelByPosition;
+      isRecoDecay = isRecoDecayByPosition;
+      isFake = isFakeByPosition;
+      
+    }
+    
     if (matchedTrackRef) {
       
       // fill global counters
       fTrackCounters->Count(Form("track:matched/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
       
       // track matched with a trackRef that is not reconstructible
-      if (!matchedTrackRef->IsValid(fRequestedStationMask, fRequest2ChInSameSt45)) {
+      if (isMatchedYet) {
        
        containMatchedYetTrack[0] = kTRUE;
        if (trigger) containMatchedYetTrack[1] = kTRUE;
        
        // fill global counters
        fTrackCounters->Count(Form("track:matchedyet/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-       fFakeTrackCounters->Count(Form("track:matchedyet/run:%d/file:%s/event:%d/%s/%s/%s/%s", fCurrentRunNumber, fCurrentFileName.Data(),
-                                      esd->GetEventNumberInFile(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+       
+       // fill histograms
+       FillHistoTrack(2, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) 
+         FillHistoTrack(2+kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       
       }
       
       // fill histograms
-      if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) {
-       if (nClusters > 0) ((TH1F*)fList->UncheckedAt(kFractionOfMatchedClusters))->Fill(((Float_t) nMatchClusters) / ((Float_t) nClusters));
-       ((TH1F*)fList->UncheckedAt(kNumberOfClustersMC))->Fill(matchedTrackRef->GetNClusters());
-       ((TH1F*)fList->UncheckedAt(kNumberOfClustersM))->Fill(nClusters);
-       ((TH1F*)fList->UncheckedAt(kNumberOfChamberHitM))->Fill(nChamberHit);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofM))->Fill(normalizedChi2);
-       ((TH1F*)fList->UncheckedAt(kPM))->Fill(p);
-       ((TH1F*)fList->UncheckedAt(kPtM))->Fill(pT);
-       ((TH1F*)fList->UncheckedAt(kEtaM))->Fill(eta);
-       ((TH1F*)fList->UncheckedAt(kPhiM))->Fill(phi);
-       ((TH1F*)fList->UncheckedAt(kDCAM))->Fill(dca);
-       ((TH1F*)fList->UncheckedAt(kRAbsM))->Fill(rAbs);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNClustersM))->Fill(nClusters,normalizedChi2);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNChamberHitM))->Fill(nChamberHit,normalizedChi2);
-      }
+      if (nClusters > 0) ((TH1F*)fList->UncheckedAt(2*kNhistTrack+kFractionOfMatchedClusters))->Fill(((Float_t) nMatchClusters) / ((Float_t) nClusters));
+      ((TH1F*)fList->UncheckedAt(2*kNhistTrack+kNumberOfClustersMC))->Fill(matchedTrackRef->GetNClusters());
+      FillHistoTrack(1, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+      if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) 
+       FillHistoTrack(1+kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
       
       // flag matched tracks
-      esdTrack->SetLabel(matchedTrackRef->GetUniqueID());
+      mcLabels[iTrack] = matchedTrackRef->GetUniqueID();
       
-      // remove already matched trackRefs
+      // move already matched trackRefs
+      usedTrackRefStore->Add(*matchedTrackRef);
       trackRefStore->Remove(*matchedTrackRef);
       
     } else {
       
-      containFakeTrack[0] = kTRUE;
-      if (trigger) containFakeTrack[1] = kTRUE;
-      
-      // fill global counters
-      fTrackCounters->Count(Form("track:fake/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-      fFakeTrackCounters->Count(Form("track:fake/run:%d/file:%s/event:%d/%s/%s/%s/%s", fCurrentRunNumber, fCurrentFileName.Data(),
-                                    esd->GetEventNumberInFile(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-      
-      // fill histograms
-      if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) {
-       ((TH1F*)fList->UncheckedAt(kNumberOfClustersF))->Fill(nClusters);
-       ((TH1F*)fList->UncheckedAt(kNumberOfChamberHitF))->Fill(nChamberHit);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofF))->Fill(normalizedChi2);
-       ((TH1F*)fList->UncheckedAt(kPF))->Fill(p);
-       ((TH1F*)fList->UncheckedAt(kPtF))->Fill(pT);
-       ((TH1F*)fList->UncheckedAt(kEtaF))->Fill(eta);
-       ((TH1F*)fList->UncheckedAt(kPhiF))->Fill(phi);
-       ((TH1F*)fList->UncheckedAt(kDCAF))->Fill(dca);
-       ((TH1F*)fList->UncheckedAt(kRAbsF))->Fill(rAbs);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNClustersF))->Fill(nClusters,normalizedChi2);
-       ((TH1F*)fList->UncheckedAt(kChi2PerDofVsNChamberHitF))->Fill(nChamberHit,normalizedChi2);
+      if (decayLabel >= 0) {
+       
+       // fill global counters
+       fTrackCounters->Count(Form("track:decay/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+       
+       // track matched with a decay that has not be tagged reconstructible
+       if (!isRecoDecay) {
+         
+         // fill global counters
+         fTrackCounters->Count(Form("track:decayyet/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+         
+         // fill histograms
+         FillHistoTrack(4, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+         if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) 
+           FillHistoTrack(4+kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+         
+       }
+       
+       // fill histograms
+       FillHistoTrack(3, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) 
+         FillHistoTrack(3+kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       
+       // flag decay tracks
+       mcLabels[iTrack] = decayLabel;
+       
       }
       
-      // flag fake tracks
-      esdTrack->SetLabel(-1);
-      
-      // store fake tracks
-      fakeTrackStore->Add(*muonTrack);
+      if (isFake || fDecayAsFake) {
+       
+       containFakeTrack[0] = kTRUE;
+       if (trigger) containFakeTrack[1] = kTRUE;
+       
+       // fill global counters
+       fTrackCounters->Count(Form("track:fake/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+       
+       // fill histograms
+       FillHistoTrack(5, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       if ((!fMatchTrig || trigger) && (!fApplyAccCut || inAcc)) 
+         FillHistoTrack(5+kNhistTrack, nClusters, nChamberHit, normalizedChi2, p, pT, eta, phi, dca, thetaTrackAbsEnd, pdca, rAbs);
+       
+       // flag fake tracks
+       mcLabels[iTrack] = -1;
+       
+       // store fake tracks
+       fakeTrackStore->Add(*muonTrack);
+       
+      }
       
     }
     
   } // end of loop over ESD tracks
   
   // fill histogram and global counters
-  ((TH1F*)fList->UncheckedAt(kNumberOfTracks))->Fill(nTrackerTracks);
+  ((TH1F*)fList->UncheckedAt(2*kNhistTrack+kNumberOfTracks))->Fill(nTrackerTracks);
   if (containTrack[0]) fEventCounters->Count(Form("event:any/run:%d/trig:any/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
   if (containTrack[1]) fEventCounters->Count(Form("event:any/run:%d/trig:yes/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
   if (containFakeTrack[0]) fEventCounters->Count(Form("event:fake/run:%d/trig:any/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
@@ -610,19 +744,22 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
       if (nAdditionalTracks > 0) {
        
        // fill histogram and global counters
-       ((TH1F*)fList->UncheckedAt(kNumberOfAdditionalTracks))->Fill(nAdditionalTracks);
+       ((TH1F*)fList->UncheckedAt(2*kNhistTrack+kNumberOfAdditionalTracks))->Fill(nAdditionalTracks);
        fEventCounters->Count(Form("event:additional/run:%d/trig:any/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
        if (!containUnmatchedFake) { // all matched
-         fTrackCounters->Count(Form("track:additional/run:%d/trig:yes/%s/acc:unknown/%s", fCurrentRunNumber, selected.Data(), centrality.Data()), nAdditionalTracks);
-         fFakeTrackCounters->Count(Form("track:additional/run:%d/file:%s/event:%d/trig:yes/%s/acc:unknown/%s", fCurrentRunNumber, fCurrentFileName.Data(), esd->GetEventNumberInFile(), selected.Data(), centrality.Data()), nAdditionalTracks);
          fEventCounters->Count(Form("event:additional/run:%d/trig:yes/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
+         fTrackCounters->Count(Form("track:additional/run:%d/trig:yes/%s/acc:unknown/%s", fCurrentRunNumber, selected.Data(), centrality.Data()), nAdditionalTracks);
+         fFakeTrackCounters->Count(Form("position:additional/label:additional/run:%d/file:%s/%s/trig:yes/%s/acc:unknown/%s", fCurrentRunNumber,
+                                        fCurrentFileName.Data(), eventNumberInFile.Data(), selected.Data(), centrality.Data()), nAdditionalTracks);
        } else if (!containMatchedFake) { // none matched
          fTrackCounters->Count(Form("track:additional/run:%d/trig:no/%s/acc:unknown/%s", fCurrentRunNumber, selected.Data(), centrality.Data()), nAdditionalTracks);
-         fFakeTrackCounters->Count(Form("track:additional/run:%d/file:%s/event:%d/trig:no/%s/acc:unknown/%s", fCurrentRunNumber, fCurrentFileName.Data(), esd->GetEventNumberInFile(), selected.Data(), centrality.Data()), nAdditionalTracks);
+         fFakeTrackCounters->Count(Form("position:additional/label:additional/run:%d/file:%s/%s/trig:no/%s/acc:unknown/%s", fCurrentRunNumber,
+                                        fCurrentFileName.Data(), eventNumberInFile.Data(), selected.Data(), centrality.Data()), nAdditionalTracks);
        } else { // mixed
-         fTrackCounters->Count(Form("track:additional/run:%d/trig:unknown/%s/acc:unknown/%s", fCurrentRunNumber, selected.Data(), centrality.Data()), nAdditionalTracks);
-         fFakeTrackCounters->Count(Form("track:additional/run:%d/file:%s/event:%d/trig:unknown/%s/acc:unknown/%s", fCurrentRunNumber, fCurrentFileName.Data(), esd->GetEventNumberInFile(), selected.Data(), centrality.Data()), nAdditionalTracks);
          fEventCounters->Count(Form("event:additional/run:%d/trig:yes/%s/%s", fCurrentRunNumber, selected.Data(), centrality.Data()));
+         fTrackCounters->Count(Form("track:additional/run:%d/trig:unknown/%s/acc:unknown/%s", fCurrentRunNumber, selected.Data(), centrality.Data()), nAdditionalTracks);
+         fFakeTrackCounters->Count(Form("position:additional/label:additional/run:%d/file:%s/%s/trig:unknown/%s/acc:unknown/%s", fCurrentRunNumber,
+                                        fCurrentFileName.Data(), eventNumberInFile.Data(), selected.Data(), centrality.Data()), nAdditionalTracks);
        }
        
       }
@@ -632,6 +769,7 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
   }
   
   // clean memory
+  delete usedTrackRefStore;
   delete fakeTrackStore;
   
   // double loop over ESD tracks, build pairs and fill histograms and counters according to their label
@@ -640,7 +778,7 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
     AliESDMuonTrack* muonTrack1 = esd->GetMuonTrack(iTrack1);
     
     // skip ghosts
-    if (!muonTrack1->ContainTrackerData()) continue;
+    if (!IsSelected(*muonTrack1)) continue;
     
     // get track info
     Bool_t trigger1 = muonTrack1->ContainTriggerData();
@@ -648,14 +786,14 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
     Double_t eta1 = muonTrack1->Eta();
     Bool_t acc1 = (thetaAbs1 >= 2. && thetaAbs1 <= 10. && eta1 >= -4. && eta1 <= -2.5);
     Short_t charge1 = muonTrack1->Charge();
-    Int_t label1 = muonTrack1->GetLabel();
+    Int_t label1 = mcLabels[iTrack1];
     muonTrack1->LorentzP(vMu1);
     
     for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
       AliESDMuonTrack* muonTrack2 = esd->GetMuonTrack(iTrack2);
       
       // skip ghosts
-      if (!muonTrack2->ContainTrackerData()) continue;
+      if (!IsSelected(*muonTrack2)) continue;
       
       // keep only opposite sign pairs
       Short_t charge2 = muonTrack2->Charge();
@@ -666,7 +804,7 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
       Double_t thetaAbs2 = TMath::ATan(muonTrack2->GetRAtAbsorberEnd()/505.) * TMath::RadToDeg();
       Double_t eta2 = muonTrack2->Eta();
       Bool_t acc2 = (thetaAbs2 >= 2. && thetaAbs2 <= 10. && eta2 >= -4. && eta2 <= -2.5);
-      Int_t label2 = muonTrack2->GetLabel();
+      Int_t label2 = mcLabels[iTrack2];
       muonTrack2->LorentzP(vMu2);
       
       // compute kinematics of the pair
@@ -686,18 +824,13 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
       else trig += "0";
       
       // acceptance condition
-      Bool_t inAcc = (acc1 && acc2 && eta >= -4. && eta <= -2.5);
+      Bool_t inAcc = (acc1 && acc2 && y >= -4. && y <= -2.5);
       TString acc = inAcc ? "acc:in" : "acc:out";
       
       // fill global histograms
-      if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc)) {
-       ((TH1F*)fList2->UncheckedAt(k2Mass))->Fill(mass);
-       ((TH1F*)fList2->UncheckedAt(k2P))->Fill(p);
-       ((TH1F*)fList2->UncheckedAt(k2Pt))->Fill(pt);
-       ((TH1F*)fList2->UncheckedAt(k2Y))->Fill(y);
-       ((TH1F*)fList2->UncheckedAt(k2Eta))->Fill(eta);
-       ((TH1F*)fList2->UncheckedAt(k2Phi))->Fill(phi);
-      }
+      FillHistoPair(0, mass, p, pt, y, eta, phi);
+      if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc))
+       FillHistoPair(kNhistPair, mass, p, pt, y, eta, phi);
       
       TString pair = "pair:";
       
@@ -706,40 +839,25 @@ void AliAnalysisTaskMuonFakes::UserExec(Option_t *)
        
        pair += "matched";
        
-       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc)) {
-         ((TH1F*)fList2->UncheckedAt(k2MassM))->Fill(mass);
-         ((TH1F*)fList2->UncheckedAt(k2PM))->Fill(p);
-         ((TH1F*)fList2->UncheckedAt(k2PtM))->Fill(pt);
-         ((TH1F*)fList2->UncheckedAt(k2YM))->Fill(y);
-         ((TH1F*)fList2->UncheckedAt(k2EtaM))->Fill(eta);
-         ((TH1F*)fList2->UncheckedAt(k2PhiM))->Fill(phi);
-       }
+       FillHistoPair(1, mass, p, pt, y, eta, phi);
+       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc))
+         FillHistoPair(1+kNhistPair, mass, p, pt, y, eta, phi);
        
       } else if (label1 >= 0 || label2 >= 0) {
        
        pair += "1fake";
        
-       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc)) {
-         ((TH1F*)fList2->UncheckedAt(k2MassF1))->Fill(mass);
-         ((TH1F*)fList2->UncheckedAt(k2PF1))->Fill(p);
-         ((TH1F*)fList2->UncheckedAt(k2PtF1))->Fill(pt);
-         ((TH1F*)fList2->UncheckedAt(k2YF1))->Fill(y);
-         ((TH1F*)fList2->UncheckedAt(k2EtaF1))->Fill(eta);
-         ((TH1F*)fList2->UncheckedAt(k2PhiF1))->Fill(phi);
-       }
+       FillHistoPair(2, mass, p, pt, y, eta, phi);
+       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc))
+         FillHistoPair(2+kNhistPair, mass, p, pt, y, eta, phi);
        
       } else {
        
        pair += "2fakes";
        
-       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc)) {
-         ((TH1F*)fList2->UncheckedAt(k2MassF2))->Fill(mass);
-         ((TH1F*)fList2->UncheckedAt(k2PF2))->Fill(p);
-         ((TH1F*)fList2->UncheckedAt(k2PtF2))->Fill(pt);
-         ((TH1F*)fList2->UncheckedAt(k2YF2))->Fill(y);
-         ((TH1F*)fList2->UncheckedAt(k2EtaF2))->Fill(eta);
-         ((TH1F*)fList2->UncheckedAt(k2PhiF2))->Fill(phi);
-       }
+       FillHistoPair(3, mass, p, pt, y, eta, phi);
+       if ((!fMatchTrig || (trigger1 && trigger2)) && (!fApplyAccCut || inAcc))
+         FillHistoPair(3+kNhistPair, mass, p, pt, y, eta, phi);
        
       }
       
@@ -766,9 +884,17 @@ void AliAnalysisTaskMuonFakes::NotifyRun()
 {
   /// Prepare processing of new run: load corresponding OCDB objects...
   
+  // load OCDB objects only once
+  if (fSigmaCut > 0) return;
+  
+  // set OCDB location
+  AliCDBManager* cdbm = AliCDBManager::Instance();
+  if (cdbm->IsDefaultStorageSet()) printf("FakeTask: CDB default storage already set!\n");
+  else cdbm->SetDefaultStorage(fRecoParamLocation.Data());
+  if (cdbm->GetRun() > -1) printf("FakeTask: run number already set!\n");
+  else cdbm->SetRun(fCurrentRunNumber);
+  
   // load necessary data from OCDB
-  AliCDBManager::Instance()->SetDefaultStorage(fRecoParamLocation.Data());
-  AliCDBManager::Instance()->SetRun(fCurrentRunNumber);
   AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
   if (!recoParam) {
     fRequestedStationMask = 0;
@@ -785,8 +911,13 @@ void AliAnalysisTaskMuonFakes::NotifyRun()
   // get from recoParam whether a track need 2 chambers hit in the same station (4 or 5) or not to be reconstructible
   fRequest2ChInSameSt45 = !recoParam->MakeMoreTrackCandidates();
   
-  // get sigma cut from recoParam to associate clusters with TrackRefs in case the labels are not used
-  fSigmaCut = (recoParam->ImproveTracks()) ? recoParam->GetSigmaCutForImprovement() : recoParam->GetSigmaCutForTracking();
+  // get sigma cut to associate clusters with TrackRefs from recoParam if not already set manually
+  if (fExternalSigmaCut > 0) fSigmaCut = fExternalSigmaCut;
+  else if (recoParam->ImproveTracks()) fSigmaCut = recoParam->GetSigmaCutForImprovement();
+  else fSigmaCut = recoParam->GetSigmaCutForTracking();
+  
+  // get the trackCuts for this run
+  if (fMuonTrackCuts) fMuonTrackCuts->SetRun(fInputHandler);
 }
 
 //________________________________________________________________________
@@ -804,61 +935,184 @@ void AliAnalysisTaskMuonFakes::Terminate(Option_t *)
   fEventCounters = static_cast<AliCounterCollection*> (GetOutputData(5));
   fPairCounters = static_cast<AliCounterCollection*> (GetOutputData(7));
   
+  TString extention = GetName();
+  extention.ReplaceAll("MUONFakes","");
+  
   // add canvas to compare histograms
-  fCanvases = new TObjArray(3);
+  fCanvases = new TObjArray(13);
   fCanvases->SetOwner();
-  TCanvas *cFakesSummary1 = new TCanvas("cFakesSummary1","cFakesSummary1",900,900);
-  fCanvases->AddAtAndExpand(cFakesSummary1, 0);
-  TCanvas *cFakesSummary2 = new TCanvas("cFakesSummary2","cFakesSummary2",1200,600);
-  fCanvases->AddAtAndExpand(cFakesSummary2, 1);
-  TCanvas *cFakesSummary3 = new TCanvas("cFakesSummary3","cFakesSummary3",900,600);
-  fCanvases->AddAtAndExpand(cFakesSummary3, 2);
-  
-  // display
-  Int_t iHist1[9] = {kNumberOfClusters, kNumberOfChamberHit, kChi2PerDof, kDCA, kRAbs, kEta, kP, kPt, kPhi};
-  cFakesSummary1->Divide(3,3);
-  for (Int_t i=0; i<9; i++) {
-    cFakesSummary1->cd(i+1);
-    cFakesSummary1->GetPad(i+1)->SetLogy();
-    ((TH1F*)fList->UncheckedAt(iHist1[i]))->SetMinimum(0.5);
-    ((TH1F*)fList->UncheckedAt(iHist1[i]))->DrawCopy();
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+1))->SetLineColor(4);
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+1))->DrawCopy("sames");
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+2))->SetLineColor(2);
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+2))->SetFillColor(2);
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+2))->SetFillStyle(3017);
-    ((TH1F*)fList->UncheckedAt(iHist1[i]+2))->DrawCopy("sames");
-  }
   
-  Int_t iHist2[2] = {kChi2PerDofVsNClusters, kChi2PerDofVsNChamberHit};
-  cFakesSummary2->Divide(2);
-  for (Int_t i=0; i<2; i++) {
-    cFakesSummary2->cd(i+1);
-    ((TH2F*)fList->UncheckedAt(iHist2[i]+1))->SetMarkerColor(4);
-    ((TH2F*)fList->UncheckedAt(iHist2[i]+1))->DrawCopy();
-    ((TH2F*)fList->UncheckedAt(iHist2[i]+2))->SetMarkerColor(2);
-    ((TH2F*)fList->UncheckedAt(iHist2[i]+2))->SetMarkerStyle(7);
-    ((TH2F*)fList->UncheckedAt(iHist2[i]+2))->DrawCopy("sames");
-  }
-  
-  Int_t iHist3[6] = {k2Mass, k2P, k2Pt, k2Y, k2Eta, k2Phi};
-  cFakesSummary3->Divide(3,2);
-  for (Int_t i=0; i<6; i++) {
-    cFakesSummary3->cd(i+1);
-    cFakesSummary3->GetPad(i+1)->SetLogy();
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]))->SetMinimum(0.5);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]))->DrawCopy();
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+1))->SetLineColor(4);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+1))->DrawCopy("sames");
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+2))->Add((TH1F*)fList2->UncheckedAt(iHist3[i]+3));
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+2))->SetLineColor(2);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+2))->SetFillColor(2);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+2))->SetFillStyle(3017);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+2))->DrawCopy("sames");
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+3))->SetLineColor(6);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+3))->SetFillColor(6);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+3))->SetFillStyle(3018);
-    ((TH1F*)fList2->UncheckedAt(iHist3[i]+3))->DrawCopy("sames");
+  TString nameSuffix[2] = {"", "S"};
+  TString titleSuffix[2] = {"", "selected "};
+  for (Int_t j = 0; j < 2; j++) {
+    
+    TCanvas *cFakesSummary11 = new TCanvas(Form("cTracks11%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                          Form("distributions of %stracks (%s)",titleSuffix[j].Data(),extention.Data()),900,900);
+    fCanvases->AddAtAndExpand(cFakesSummary11, 0+7*j);
+    TCanvas *cFakesSummary12 = new TCanvas(Form("cTracks12%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                          Form("detailled distributions of %stracks (%s)",titleSuffix[j].Data(),extention.Data()),900,900);
+    fCanvases->AddAtAndExpand(cFakesSummary12, 1+7*j);
+    TCanvas *cFakesSummary13 = new TCanvas(Form("cTracks13%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                          Form("p*DCA distributions of %stracks (%s)",titleSuffix[j].Data(),extention.Data()),600,300);
+    fCanvases->AddAtAndExpand(cFakesSummary13, 2+7*j);
+    TCanvas *cFakesSummary14 = new TCanvas(Form("cTracks14%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                          Form("detailled p*DCA distributions of %stracks (%s)",titleSuffix[j].Data(),extention.Data()),600,300);
+    fCanvases->AddAtAndExpand(cFakesSummary14, 3+7*j);
+    TCanvas *cFakesSummary21 = new TCanvas(Form("cTracks21%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                         Form("correlations at the %strack level (%s)",titleSuffix[j].Data(),extention.Data()),1200,600);
+    fCanvases->AddAtAndExpand(cFakesSummary21, 4+7*j);
+    TCanvas *cFakesSummary22 = new TCanvas(Form("cTracks22%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                         Form("detailled correlations at the %strack level (%s)",titleSuffix[j].Data(),extention.Data()),1200,600);
+    fCanvases->AddAtAndExpand(cFakesSummary22, 5+7*j);
+    TCanvas *cFakesSummary3 = new TCanvas(Form("cPairs%s_%s",nameSuffix[j].Data(),extention.Data()),
+                                         Form("distributions of %spairs (%s)",titleSuffix[j].Data(),extention.Data()),900,600);
+    fCanvases->AddAtAndExpand(cFakesSummary3, 6+7*j);
+    
+    // display
+    Int_t iHist1[9] = {kNumberOfClusters, kNumberOfChamberHit, kChi2PerDof, kDCA, kRAbs, kEta, kP, kPt, kPhi};
+    cFakesSummary11->Divide(3,3);
+    for (Int_t i=0; i<9; i++) {
+      cFakesSummary11->cd(i+1);
+      cFakesSummary11->GetPad(i+1)->SetLogy();
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack))->SetMinimum(0.5);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack))->DrawCopy();
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+1))->SetLineColor(4);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+1))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+3))->SetLineColor(kViolet-3);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+3))->SetFillColor(kViolet-3);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+3))->SetFillStyle(3018);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+3))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->SetLineColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->SetFillColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->SetFillStyle(3017);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    cFakesSummary12->Divide(3,3);
+    for (Int_t i=0; i<9; i++) {
+      cFakesSummary12->cd(i+1);
+      cFakesSummary12->GetPad(i+1)->SetLogy();
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack))->SetMinimum(0.5);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack))->DrawCopy();
+      TH1F *hClone = (TH1F*) fList->UncheckedAt(iHist1[i]+j*kNhistTrack+1)->Clone();
+      hClone->Add(((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+2)), -1);
+      hClone->SetLineColor(4);
+      hClone->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+2))->SetLineColor(7);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+2))->DrawCopy("sames");
+      hClone = (TH1F*) fList->UncheckedAt(iHist1[i]+j*kNhistTrack+3)->Clone();
+      hClone->Add(((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+4)), -1);
+      hClone->SetLineColor(3);
+      hClone->SetFillStyle(0);
+      hClone->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+4))->SetLineColor(32);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+4))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->SetLineColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->SetFillStyle(0);
+      ((TH1F*)fList->UncheckedAt(iHist1[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    Int_t iHist2[2] = {kPDCA23, kPDCA310};
+    cFakesSummary13->Divide(2,1);
+    for (Int_t i=0; i<2; i++) {
+      cFakesSummary13->cd(i+1);
+      cFakesSummary13->GetPad(i+1)->SetLogy();
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack))->SetMinimum(0.5);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack))->DrawCopy();
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+1))->SetLineColor(4);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+1))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+3))->SetLineColor(kViolet-3);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+3))->SetFillColor(kViolet-3);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+3))->SetFillStyle(3018);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+3))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->SetLineColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->SetFillColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->SetFillStyle(3017);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    cFakesSummary14->Divide(2,1);
+    for (Int_t i=0; i<2; i++) {
+      cFakesSummary14->cd(i+1);
+      cFakesSummary14->GetPad(i+1)->SetLogy();
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack))->SetMinimum(0.5);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack))->DrawCopy();
+      TH1F *hClone = (TH1F*) fList->UncheckedAt(iHist2[i]+j*kNhistTrack+1)->Clone();
+      hClone->Add(((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+2)), -1);
+      hClone->SetLineColor(4);
+      hClone->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+2))->SetLineColor(7);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+2))->DrawCopy("sames");
+      hClone = (TH1F*) fList->UncheckedAt(iHist2[i]+j*kNhistTrack+3)->Clone();
+      hClone->Add(((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+4)), -1);
+      hClone->SetLineColor(3);
+      hClone->SetFillStyle(0);
+      hClone->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+4))->SetLineColor(32);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+4))->DrawCopy("sames");
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->SetLineColor(2);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->SetFillStyle(0);
+      ((TH1F*)fList->UncheckedAt(iHist2[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    Int_t iHist3[2] = {kChi2PerDofVsNClusters, kChi2PerDofVsNChamberHit};
+    cFakesSummary21->Divide(2);
+    for (Int_t i=0; i<2; i++) {
+      cFakesSummary21->cd(i+1);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+1))->SetMarkerColor(4);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+1))->DrawCopy();
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+3))->SetMarkerColor(kViolet-3);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+3))->SetMarkerStyle(6);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+3))->DrawCopy("sames");
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->SetMarkerColor(2);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->SetMarkerStyle(7);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    cFakesSummary22->Divide(2);
+    for (Int_t i=0; i<2; i++) {
+      cFakesSummary22->cd(i+1);
+      TH2F *hClone = (TH2F*) fList->UncheckedAt(iHist3[i]+j*kNhistTrack+1)->Clone();
+      hClone->Add(((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+2)), -1);
+      hClone->SetMarkerColor(4);
+      hClone->DrawCopy();
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+2))->SetMarkerColor(7);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+2))->SetMarkerStyle(6);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+2))->DrawCopy("sames");
+      hClone = (TH2F*) fList->UncheckedAt(iHist3[i]+j*kNhistTrack+3)->Clone();
+      hClone->Add(((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+4)), -1);
+      hClone->SetMarkerColor(kViolet-3);
+      hClone->SetMarkerStyle(6);
+      hClone->DrawCopy("sames");
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+4))->SetLineColor(32);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+4))->SetMarkerStyle(6);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+4))->DrawCopy("sames");
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->SetMarkerColor(2);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->SetMarkerStyle(7);
+      ((TH2F*)fList->UncheckedAt(iHist3[i]+j*kNhistTrack+5))->DrawCopy("sames");
+    }
+    
+    Int_t iHist4[6] = {k2Mass, k2P, k2Pt, k2Y, k2Eta, k2Phi};
+    cFakesSummary3->Divide(3,2);
+    for (Int_t i=0; i<6; i++) {
+      cFakesSummary3->cd(i+1);
+      cFakesSummary3->GetPad(i+1)->SetLogy();
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair))->SetMinimum(0.5);
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair))->DrawCopy();
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+1))->SetLineColor(4);
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+1))->DrawCopy("sames");
+      TH1F* hClone = (TH1F*) fList2->UncheckedAt(iHist4[i]+j*kNhistPair+2)->Clone();
+      hClone->Add((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+3));
+      hClone->SetLineColor(2);
+      hClone->SetFillColor(2);
+      hClone->SetFillStyle(3017);
+      hClone->DrawCopy("sames");
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+3))->SetLineColor(6);
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+3))->SetFillColor(6);
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+3))->SetFillStyle(3018);
+      ((TH1F*)fList2->UncheckedAt(iHist4[i]+j*kNhistPair+3))->DrawCopy("sames");
+    }
+    
   }
   
   // print
@@ -866,7 +1120,7 @@ void AliAnalysisTaskMuonFakes::Terminate(Option_t *)
     printf("\nGlobal statistics of reconstructed tracks matched or not with the trigger:\n");
     fTrackCounters->Print("track/trig");
     printf("\nGlobal statistics of pathological tracks matched or not with the trigger:\n");
-    fFakeTrackCounters->Print("track/trig");
+    fFakeTrackCounters->Print("label/position/trig");
     printf("\nDetailled statistics of tracks matched per label vs position:\n");
     fMatchedTrackCounters->Print("label/position");
     printf("\nGlobal statistics of events containing pathological tracks:\n");
@@ -881,6 +1135,62 @@ void AliAnalysisTaskMuonFakes::Terminate(Option_t *)
   printf("\nREMINDER: results are relevent provided that you use the same recoParams as for the reconstruction\n\n");
 }
 
+
+//________________________________________________________________________
+Bool_t AliAnalysisTaskMuonFakes::IsSelected(AliESDMuonTrack &esdTrack)
+{
+  /// return kTRUE if the track pass the section criteria
+  
+  // make sure to skip ghosts
+  if (!esdTrack.ContainTrackerData()) return kFALSE;
+  
+  // apply standard track cuts if any
+  if (fMuonTrackCuts && !fMuonTrackCuts->IsSelected(&esdTrack)) return kFALSE;
+  
+  // apply specific chi2 cut if required
+  if (fChi2Cut > 0. && esdTrack.GetNormalizedChi2() > fChi2Cut) return kFALSE;
+  
+  // apply specific pt cut if required
+  if (fPtCut > 0. && esdTrack.Pt() < fPtCut) return kFALSE;
+  
+  return kTRUE;
+}
+
+
+//________________________________________________________________________
+void AliAnalysisTaskMuonFakes::FillHistoTrack(Int_t histShift, Int_t nClusters, Int_t nChamberHit, Double_t normalizedChi2,
+                                             Double_t p, Double_t pT, Double_t eta, Double_t phi, Double_t dca,
+                                             Double_t thetaTrackAbsEnd, Double_t pdca, Double_t rAbs)
+{
+  /// fill global histograms at track level
+  ((TH1F*)fList->UncheckedAt(kNumberOfClusters+histShift))->Fill(nClusters);
+  ((TH1F*)fList->UncheckedAt(kNumberOfChamberHit+histShift))->Fill(nChamberHit);
+  ((TH1F*)fList->UncheckedAt(kChi2PerDof+histShift))->Fill(normalizedChi2);
+  ((TH1F*)fList->UncheckedAt(kP+histShift))->Fill(p);
+  ((TH1F*)fList->UncheckedAt(kPt+histShift))->Fill(pT);
+  ((TH1F*)fList->UncheckedAt(kEta+histShift))->Fill(eta);
+  ((TH1F*)fList->UncheckedAt(kPhi+histShift))->Fill(phi);
+  ((TH1F*)fList->UncheckedAt(kDCA+histShift))->Fill(dca);
+  if (thetaTrackAbsEnd > 2 && thetaTrackAbsEnd <= 3) ((TH1F*)fList->UncheckedAt(kPDCA23+histShift))->Fill(pdca);
+  else if (thetaTrackAbsEnd > 3 && thetaTrackAbsEnd < 10) ((TH1F*)fList->UncheckedAt(kPDCA310+histShift))->Fill(pdca);
+  ((TH1F*)fList->UncheckedAt(kRAbs+histShift))->Fill(rAbs);
+  ((TH2F*)fList->UncheckedAt(kChi2PerDofVsNClusters+histShift))->Fill(nClusters,normalizedChi2);
+  ((TH2F*)fList->UncheckedAt(kChi2PerDofVsNChamberHit+histShift))->Fill(nChamberHit,normalizedChi2);
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskMuonFakes::FillHistoPair(Int_t histShift, Double_t mass, Double_t p, Double_t pt,
+                                            Double_t y, Double_t eta, Double_t phi)
+{
+  /// fill global histograms at pair level
+  ((TH1F*)fList2->UncheckedAt(k2Mass+histShift))->Fill(mass);
+  ((TH1F*)fList2->UncheckedAt(k2P+histShift))->Fill(p);
+  ((TH1F*)fList2->UncheckedAt(k2Pt+histShift))->Fill(pt);
+  ((TH1F*)fList2->UncheckedAt(k2Y+histShift))->Fill(y);
+  ((TH1F*)fList2->UncheckedAt(k2Eta+histShift))->Fill(eta);
+  ((TH1F*)fList2->UncheckedAt(k2Phi+histShift))->Fill(phi);
+}
+
 //________________________________________________________________________
 Int_t AliAnalysisTaskMuonFakes::RemoveConnectedFakes(AliMUONVTrackStore &fakeTrackStore, AliMUONVTrackStore &trackRefStore,
                                                     TString &selected, TString &centrality)
@@ -911,13 +1221,14 @@ Int_t AliAnalysisTaskMuonFakes::RemoveConnectedFakes(AliMUONVTrackStore &fakeTra
       
       // get the number of connected clusters
       Int_t nConnectedClusters = 0;
-      if (fUseLabel) { // by using the MC label
+      if (fUseLabel || fCombineMCId) { // by using the MC label
        for (Int_t iCl = 0; iCl < fakeTrack->GetNClusters(); iCl++)
          if (((AliMUONTrackParam*) fakeTrack->GetTrackParamAtCluster()->UncheckedAt(iCl))->GetClusterPtr()->GetMCLabel() == label)
            nConnectedClusters++;
-      } else { // by comparing cluster/TrackRef positions
+      }
+      if (!fUseLabel || fCombineMCId) { // by comparing cluster/TrackRef positions
        Bool_t compTrack[10];
-       nConnectedClusters = fakeTrack->FindCompatibleClusters(*trackRef, fSigmaCut, compTrack);
+       nConnectedClusters = TMath::Max(nConnectedClusters, fakeTrack->FindCompatibleClusters(*trackRef, fSigmaCut, compTrack));
       }
       
       // skip non-connected fake tracks
@@ -957,10 +1268,11 @@ Int_t AliAnalysisTaskMuonFakes::RemoveConnectedFakes(AliMUONVTrackStore &fakeTra
       TString acc = (thetaTrackAbsEnd >= 2. && thetaTrackAbsEnd <= 10. && eta >= -4. && eta <= -2.5) ? "acc:in" : "acc:out";
       
       // fill histogram and counters
-      ((TH1F*)fList->UncheckedAt(kFractionOfConnectedClusters))->Fill(fractionOfConnectedClusters);
+      TString eventNumberInFile = (fDisableDetailedCounters) ? "event:any" : Form("event:%d",esd->GetEventNumberInFile());
+      ((TH1F*)fList->UncheckedAt(2*kNhistTrack+kFractionOfConnectedClusters))->Fill(fractionOfConnectedClusters);
       fTrackCounters->Count(Form("track:connected/run:%d/%s/%s/%s/%s", fCurrentRunNumber, trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
-      fFakeTrackCounters->Count(Form("track:connected/run:%d/file:%s/event:%d/%s/%s/%s/%s", fCurrentRunNumber, fCurrentFileName.Data(),
-                                    esd->GetEventNumberInFile(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
+      fFakeTrackCounters->Count(Form("position:connected/label:connected/run:%d/file:%s/%s/%s/%s/%s/%s", fCurrentRunNumber, fCurrentFileName.Data(),
+                                    eventNumberInFile.Data(), trig.Data(), selected.Data(), acc.Data(), centrality.Data()));
       
       // remove the most connected fake track
       fakeTrackStore.Remove(*connectedFake);
@@ -973,3 +1285,301 @@ Int_t AliAnalysisTaskMuonFakes::RemoveConnectedFakes(AliMUONVTrackStore &fakeTra
   
 }
 
+//________________________________________________________________________
+Int_t AliAnalysisTaskMuonFakes::IsDecay(Int_t nClusters, Int_t *chId, Int_t *labels,
+                                       Bool_t &isReconstructible, Int_t &lastCh) const
+{
+  /// Check whether this combination of clusters correspond to a decaying particle or not:
+  /// More than 50% of clusters, including 1 before and 1 after the dipole, must be connected.
+  /// - Return the MC label of the most downstream decay product or -1 if not a decay.
+  /// - "isReconstructible" tells if the combination of matched clusters fulfil the reconstruction criteria.
+  /// - As soon as we realized the decay chain cannot be tagged as reconstructible, we reject any chain ending
+  ///   on a chamber equal to or upstream "lastCh" (used to select the best chain in case of multiple choices).
+  /// - "lastCh" is reset the most downstream chamber of the found decay chain if any.
+  
+  Int_t halfCluster = nClusters/2;
+  
+  // loop over last clusters (if nClusters left < halfCluster the conditions cannot be fulfilled)
+  Int_t firstLabel = -1, decayLabel = -1;
+  isReconstructible = kFALSE;
+  for (Int_t iCluster1 = nClusters-1; iCluster1 >= halfCluster; iCluster1--) {
+    
+    // if the last cluster is not on station 4 or 5 the conditions cannot be fulfilled
+    if (chId[iCluster1] < 6) break;
+    
+    // skip clusters with no label or same label as at the begining of the previous step (already tested)
+    if (labels[iCluster1] < 0 || labels[iCluster1] == firstLabel) continue;
+    
+    // is there any chance the hypothetical decay chain can be tagged reconstructible?
+    Int_t stationId = chId[iCluster1]/2;
+    Int_t stationMask = 1 << stationId;
+    Int_t requestedStations = fRequestedStationMask >> stationId;
+    Bool_t isValid = ((1 & requestedStations) == requestedStations);
+    
+    // if not: check whether we can find a better chain than already found
+    if (!isValid && chId[iCluster1] <= lastCh) break;
+    
+    // count the number of fired chambers on stations 4 & 5
+    Int_t nChHitInSt45[2] = {0, 0};
+    nChHitInSt45[stationId-3] = 1;
+    Int_t currentCh = chId[iCluster1];
+    
+    // get the ancestors
+    TArrayI chainLabels(100);
+    Int_t nParticles = 0;
+    Int_t currentLabel = labels[iCluster1];
+    do {
+      chainLabels[nParticles++] = currentLabel;
+      if (nParticles >= chainLabels.GetSize()) chainLabels.Set(2*chainLabels.GetSize());
+      AliMCParticle* currentParticle = static_cast<AliMCParticle*>(fMCEvent->GetTrack(currentLabel));
+      currentLabel = (currentParticle) ? currentParticle->GetMother() : -1;
+    } while (currentLabel >= 0);
+    
+    // Loop over prior clusters
+    firstLabel = labels[iCluster1];
+    Int_t nCompatibleLabel = 1;
+    Int_t currentParticle = 0;
+    for (Int_t iCluster2 = iCluster1-1; iCluster2 >= 0; iCluster2--) {
+      
+      // if the number of clusters left is not enough the conditions cannot be fulfilled
+      if (iCluster2 < halfCluster-nCompatibleLabel) break;
+      
+      if (labels[iCluster2] < 0) continue;
+      
+      // check if the cluster belong to the same particle or one of its ancestors
+      Bool_t matchFound = kFALSE;
+      for (Int_t iParticle = currentParticle; iParticle < nParticles; iParticle++) {
+       if (labels[iCluster2] == chainLabels[iParticle]) {
+         currentParticle = iParticle;
+         matchFound = kTRUE;
+         break;
+       }
+      }
+      if (matchFound) nCompatibleLabel++;
+      else continue;
+      
+      // add this station to the mask
+      stationId = chId[iCluster2]/2;
+      stationMask |= 1 << stationId;
+      
+      // count the number of fired chamber on stations 4 & 5
+      if (stationId > 2 && chId[iCluster2] < currentCh) {
+       nChHitInSt45[stationId-3]++;
+       currentCh = chId[iCluster2];
+      }
+      
+      // check if we matched enough clusters to tag the track as a decay
+      if (nCompatibleLabel <= halfCluster || chId[iCluster2] > 3 || chainLabels[currentParticle] == firstLabel) continue;
+      
+      // check if this chain is better than already found
+      if (chId[iCluster1] > lastCh) {
+       decayLabel = firstLabel;
+       lastCh = chId[iCluster1];
+      }
+      
+      // is there enough matched clusters on station 4 & 5 to make the track reconstructible?
+      Bool_t isEnoughClOnSt45 = fRequest2ChInSameSt45 ? (nChHitInSt45[0] == 2 || nChHitInSt45[1] == 2)
+                                                     : (nChHitInSt45[0]+nChHitInSt45[1] >= 2);
+      
+      // is there any chance the current decay chain can still be tagged reconstructible?
+      requestedStations = fRequestedStationMask >> stationId;
+      isValid = (((stationMask >> stationId) & requestedStations) == requestedStations &&
+                (chId[iCluster2] > 5 || isEnoughClOnSt45));
+      
+      // if not then we cannot do better with this trial
+      if (!isValid) break;
+      
+      // take in priority the decay chain that can be tagged reconstructible
+      if (((stationMask & fRequestedStationMask) == fRequestedStationMask) && isEnoughClOnSt45) {
+       lastCh = chId[iCluster1];
+       isReconstructible = kTRUE;
+       return firstLabel;
+      }
+      
+    }
+    
+  }
+  
+  return decayLabel;
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskMuonFakes::AddCompatibleClusters(const AliMUONTrack &track, const AliMUONTrack &trackRef,
+                                                    TArrayI *labels, Int_t *nLabels) const
+{
+  /// Try to match clusters between track and trackRef and add the corresponding MC labels to the arrays
+  
+  Double_t chi2Max = 2. * fSigmaCut * fSigmaCut; // 2 because 2 quantities in chi2
+  
+  // Loop over clusters of first track
+  Int_t nCl1 = track.GetNClusters();
+  for(Int_t iCl1 = 0; iCl1 < nCl1; iCl1++) {
+    AliMUONVCluster *cluster1 = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(iCl1))->GetClusterPtr();
+    
+    // Loop over clusters of second track
+    Int_t nCl2 = trackRef.GetNClusters();
+    for(Int_t iCl2 = 0; iCl2 < nCl2; iCl2++) {
+      AliMUONVCluster *cluster2 = static_cast<AliMUONTrackParam*>(trackRef.GetTrackParamAtCluster()->UncheckedAt(iCl2))->GetClusterPtr();
+      
+      // check DE Id
+      if (cluster1->GetDetElemId() != cluster2->GetDetElemId()) continue;
+      
+      // check local chi2
+      Double_t dX = cluster1->GetX() - cluster2->GetX();
+      Double_t dY = cluster1->GetY() - cluster2->GetY();
+      Double_t chi2 = dX * dX / (cluster1->GetErrX2() + cluster2->GetErrX2()) + dY * dY / (cluster1->GetErrY2() + cluster2->GetErrY2());
+      if (chi2 > chi2Max) continue;
+      
+      // expand array if needed
+      if (nLabels[iCl1] >= labels[iCl1].GetSize()) labels[iCl1].Set(2*labels[iCl1].GetSize());
+      
+      // save label
+      labels[iCl1][nLabels[iCl1]] = static_cast<Int_t>(trackRef.GetUniqueID());
+      nLabels[iCl1]++;
+      break;
+      
+    }
+    
+  }
+  
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisTaskMuonFakes::IsDecayByLabel(const AliMUONTrack &track, Bool_t &isReconstructible,
+                                              Int_t &lastCh) const
+{
+  /// Check whether this track correspond to a decaying particle by using cluster MC labels.
+  /// "lastCh" contains the chamber Id of the most downstream chamber hit by the decay chain
+  if (fPrintDecayChain) printf("\nBY LABEL\n");
+  
+  Int_t nClusters = track.GetNClusters();
+  if (nClusters <= 0) return -1;
+  Int_t *chId = new Int_t[nClusters];
+  Int_t *labels = new Int_t[nClusters];
+  
+  // copy labels and chamber Ids
+  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+    AliMUONVCluster* cluster = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
+    chId[iCluster] = cluster->GetChamberId();
+    labels[iCluster] = cluster->GetMCLabel();
+    if (fPrintDecayChain) {
+      printf("ch%d: %d",chId[iCluster],labels[iCluster]);
+      Int_t currentLabel = labels[iCluster];
+      while (currentLabel >= 0) {
+       AliMCParticle* currentParticle = static_cast<AliMCParticle*>(fMCEvent->GetTrack(currentLabel));
+       printf("(%s)",(currentParticle) ? currentParticle->Particle()->GetName() : "");
+       if (currentLabel == labels[iCluster]) printf(" (");
+       currentLabel = (currentParticle) ? currentParticle->GetMother() : -1;
+       if (currentLabel >= 0) printf(" %d",currentLabel);
+      }
+      printf(" )\n");
+    }
+  }
+  
+  // look for decay
+  lastCh = 0;
+  Int_t decayLabel = IsDecay(nClusters, chId, labels, isReconstructible, lastCh);
+  if (fPrintDecayChain) printf("---> decayLabel = %d (reco = %d / lastCh = %d)\n",decayLabel,isReconstructible,lastCh);
+  
+  delete[] chId;
+  delete[] labels;
+  
+  return decayLabel;
+}
+
+//________________________________________________________________________
+Int_t AliAnalysisTaskMuonFakes::IsDecayByPosition(const AliMUONTrack &track, const AliMUONVTrackStore &trackRefStore,
+                                                 const AliMUONVTrackStore &usedTrackRefStore, Bool_t &isReconstructible,
+                                                 Int_t &lastCh) const
+{
+  /// Check whether this track correspond to a decaying particle by comparing clusters position
+  /// All possible combinations of compatible clusters from every trackRefs are considered
+  if (fPrintDecayChain) printf("\nBY POSITION\n");
+  
+  Int_t nClusters = track.GetNClusters();
+  if (nClusters <= 0) return -1;
+  Int_t *chId = new Int_t[nClusters];
+  Int_t *nLabels = new Int_t[nClusters];
+  TArrayI *labels = new TArrayI[nClusters];
+  
+  // copy chamber Ids
+  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+    AliMUONVCluster* cluster = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
+    chId[iCluster] = cluster->GetChamberId();
+    nLabels[iCluster] = 0;
+    labels[iCluster].Set(100);
+  }
+  
+  // loop over trackRef store and add label of compatible clusters
+  TIter next1(trackRefStore.CreateIterator());
+  AliMUONTrack* trackRef;
+  while ( ( trackRef = static_cast<AliMUONTrack*>(next1()) ) )
+    AddCompatibleClusters(track, *trackRef, labels, nLabels);
+  
+  // loop over usedTrackRef store and add label of compatible clusters
+  TIter next2(usedTrackRefStore.CreateIterator());
+  while ( ( trackRef = static_cast<AliMUONTrack*>(next2()) ) )
+    AddCompatibleClusters(track, *trackRef, labels, nLabels);
+  
+  // complete the arrays of labels with "-1" if no label was found for a given cluster
+  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+    if (nLabels[iCluster] == 0) {
+      labels[iCluster][0] = -1;
+      nLabels[iCluster]++;
+    }
+  }
+  
+  // loop over all possible combinations
+  Int_t *iLabel = new Int_t[nClusters];
+  memset(iLabel,0,nClusters*sizeof(Int_t));
+  iLabel[nClusters-1] = -1;
+  Int_t *currentLabels = new Int_t[nClusters];
+  Int_t decayLabel = -1;
+  lastCh = 0;
+  isReconstructible = kFALSE;
+  while (kTRUE) {
+    
+    // go to the next combination
+    Int_t iCl = nClusters-1;
+    while (++iLabel[iCl] >= nLabels[iCl] && iCl > 0) iLabel[iCl--] = 0;
+    if (iLabel[iCl] >= nLabels[iCl]) break; // no more combination
+    
+    // copy labels
+    if (fPrintDecayChain) printf("\n");
+    for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+      currentLabels[iCluster] = labels[iCluster][iLabel[iCluster]];
+      if (fPrintDecayChain) {
+       printf("ch%d: %d",chId[iCluster],currentLabels[iCluster]);
+       Int_t currentLabel = currentLabels[iCluster];
+       while (currentLabel >= 0) {
+         AliMCParticle* currentParticle = static_cast<AliMCParticle*>(fMCEvent->GetTrack(currentLabel));
+         printf("(%s)",(currentParticle) ? currentParticle->Particle()->GetName() : "");
+         if (currentLabel == currentLabels[iCluster]) printf(" (");
+         currentLabel = (currentParticle) ? currentParticle->GetMother() : -1;
+         if (currentLabel >= 0) printf(" %d",currentLabel);
+       }
+       printf(" )\n");
+      }
+    }
+    
+    // look for decay
+    Int_t currentDecayLabel = IsDecay(nClusters, chId, currentLabels, isReconstructible, lastCh);
+    if (fPrintDecayChain) printf("---> decayLabel = %d (reco = %d / lastCh = %d)\n",currentDecayLabel,isReconstructible,lastCh);
+    if (currentDecayLabel >= 0) {
+      decayLabel = currentDecayLabel;
+      if (isReconstructible) break;
+    }
+    
+  }
+  
+  if (fPrintDecayChain) printf("------> decayLabel = %d (reco = %d / lastCh = %d)\n",decayLabel,isReconstructible,lastCh);
+  
+  delete[] chId;
+  delete[] nLabels;
+  delete[] labels;
+  delete[] iLabel;
+  delete[] currentLabels;
+  
+  return decayLabel;  
+}
+
index 9b4df63..cee3ff3 100644 (file)
 #include <TString.h>
 
 #include "AliAnalysisTaskSE.h"
+#include "AliMuonTrackCuts.h"
 
 class TObjArray;
 class AliCounterCollection;
+class AliESDMuonTrack;
 class AliMUONVTrackStore;
 class AliMUONTrack;
 
@@ -32,18 +34,45 @@ public:
   virtual void   NotifyRun();
   virtual void   Terminate(Option_t *);
   
+  /// set the flag to show the progression bar
+  void ShowProgressBar(Bool_t flag = kTRUE) { fShowProgressBar = flag; }
+  
   /// Set the flag to match reconstructed and simulated tracks by using the MC labels or by position
   void UseMCLabels(Bool_t flag = kTRUE) { fUseLabel = flag; }
   
+  /// Set the flag to combine reconstructed/simulated track matching by MC labels and by position
+  void CombineMCId(Bool_t flag = kTRUE) { fCombineMCId = flag; }
+  
+  /// Set the sigma cut to associate clusters with TrackRefs by position (instead of using recoParam)
+  void SetExternalSigmaCut(Double_t cut) { fExternalSigmaCut = cut; }
+  
   /// set the flag to fill histograms only with tracks matched with trigger or not
   void MatchTrigger(Bool_t flag = kTRUE) { fMatchTrig = flag; }
   
   /// set the flag to fill histograms only with tracks passing the acceptance cuts (Rabs, eta)
   void ApplyAccCut(Bool_t flag = kTRUE) { fApplyAccCut = flag; }
   
+  /// set specific cut value on normalized chi2 above which the track is not considered
+  void Chi2Cut(Double_t cut) { fChi2Cut = cut; }
+  
+  /// set specific cut value on minimum pt below which the track is not considered
+  void PtCut(Double_t cut) { fPtCut = cut; }
+  
+  // set standard cuts to select tracks to be considered
+  void SetMuonTrackCuts(AliMuonTrackCuts &trackCuts);
+  
   /// Set the ocdb path toward the reconstruction parameters
   void RecoParamLocation(const char* ocdbPath) { fRecoParamLocation = ocdbPath; }
   
+  /// set the flag to considere decays as fake tracks or not
+  void DecayAsFake(Bool_t flag = kTRUE) { fDecayAsFake = flag; }
+  
+  /// set the flag to print labels of connected particles and ancestors when looking for decays
+  void PrintDecayChain(Bool_t flag = kTRUE) { fPrintDecayChain = flag; }
+  
+  /// set the flag to disable the recording of event/file of problematic tracks
+  void DisableDetailedCounters(Bool_t flag = kTRUE) { fDisableDetailedCounters = flag; }
+  
   /// Return the list of summary canvases
   TObjArray* GetCanvases() {return fCanvases;}
   
@@ -54,96 +83,76 @@ private:
   /// Not implemented
   AliAnalysisTaskMuonFakes& operator = (const AliAnalysisTaskMuonFakes& rhs);
   
+  // return kTRUE if the track pass the section criteria
+  Bool_t IsSelected(AliESDMuonTrack &esdTrack);
+  
+  // fill global histograms at track level
+  void FillHistoTrack(Int_t histShift, Int_t nClusters, Int_t nChamberHit, Double_t normalizedChi2,
+                     Double_t p, Double_t pT, Double_t eta, Double_t phi, Double_t dca,
+                     Double_t thetaTrackAbsEnd, Double_t pdca, Double_t rAbs);
+  
+  /// fill global histograms at pair level
+  void FillHistoPair(Int_t histShift, Double_t mass, Double_t p, Double_t pt,
+                    Double_t y, Double_t eta, Double_t phi);
+  
   // look for fake tracks still connected to a reconstructible simulated track
   Int_t RemoveConnectedFakes(AliMUONVTrackStore &fakeTrackStore, AliMUONVTrackStore &trackRefStore,
                             TString &selected, TString &centrality);
   
+  // Check whether this combination of clusters correspond to a decaying particle or not
+  Int_t IsDecay(Int_t nClusters, Int_t *chId, Int_t *labels, Bool_t &isReconstructible, Int_t &lastCh) const;
+  
+  // Try to match clusters between track and trackRef and add the corresponding MC labels to the arrays
+  void AddCompatibleClusters(const AliMUONTrack &track, const AliMUONTrack &trackRef,
+                            TArrayI *labels, Int_t *nLabels) const;
+  
+  // Check whether this track correspond to a decaying particle by using cluster MC labels
+  Int_t IsDecayByLabel(const AliMUONTrack &track, Bool_t &isReconstructible, Int_t &lastCh) const;
+  
+  // Check whether this track correspond to a decaying particle by comparing clusters position
+  Int_t IsDecayByPosition(const AliMUONTrack &track, const AliMUONVTrackStore &trackRefStore,
+                         const AliMUONVTrackStore &usedTrackRefStore, Bool_t &isReconstructible,
+                         Int_t &lastCh) const;
+  
 private:
   
   enum histoIndex {
-    // number of tracks
-    kNumberOfTracks,           ///< number of tracks
-    kNumberOfAdditionalTracks, ///< number of additional tracks
-    
-    // number of clusters
-    kNumberOfClusters,            ///< number of clusters per track
-    kNumberOfClustersM,           ///< number of clusters per matched track
-    kNumberOfClustersF,           ///< number of clusters per fake track
-    kNumberOfClustersMC,          ///< number of clusters per MC track
-    kFractionOfMatchedClusters,   ///< fraction of matched clusters in matched tracks
-    kFractionOfConnectedClusters, ///< fraction of connected clusters in fake tracks
-    
-    // number of fired chambers
-    kNumberOfChamberHit,  ///< number of fired chambers per track
-    kNumberOfChamberHitM, ///< number of fired chambers per matched track
-    kNumberOfChamberHitF, ///< number of fired chambers per fake track
-    
-    // chi2
-    kChi2PerDof,  ///< normalized chi2 of tracks
-    kChi2PerDofM, ///< normalized chi2 of matched tracks
-    kChi2PerDofF, ///< normalized chi2 of fake tracks
-    
-    // chi2 versus number of clusters
-    kChi2PerDofVsNClusters,  ///< normalized chi2 of tracks versus number of clusters
-    kChi2PerDofVsNClustersM, ///< normalized chi2 of matched tracks versus number of clusters
-    kChi2PerDofVsNClustersF, ///< normalized chi2 of fake tracks versus number of clusters
-    
-    // chi2 versus number of fired chambers
-    kChi2PerDofVsNChamberHit,  ///< normalized chi2 of tracks versus number of fired chambers
-    kChi2PerDofVsNChamberHitM, ///< normalized chi2 of matched tracks versus number of fired chambers
-    kChi2PerDofVsNChamberHitF, ///< normalized chi2 of fake tracks versus number of fired chambers
-    
-    // physics quantities
-    kP,     ///< momentum of tracks
-    kPM,    ///< momentum of matched tracks
-    kPF,    ///< momentum of fake tracks
-    kPt,    ///< transverse momentum of tracks
-    kPtM,   ///< transverse momentum of matched tracks
-    kPtF,   ///< transverse momentum of fake tracks
-    kEta,   ///< pseudo-rapidity of tracks
-    kEtaM,  ///< pseudo-rapidity of matched tracks
-    kEtaF,  ///< pseudo-rapidity of fake tracks
-    kPhi,   ///< phi angle of tracks
-    kPhiM,  ///< phi angle of matched tracks
-    kPhiF,  ///< phi angle of fake tracks
-    kDCA,   ///< DCA of tracks
-    kDCAM,  ///< DCA of matched tracks
-    kDCAF,  ///< DCA of fake tracks
-    kRAbs,  ///< R of tracks at the end of the absorber
-    kRAbsM, ///< R of matched tracks at the end of the absorber
-    kRAbsF, ///< R of fake tracks at the end of the absorber
+    kNumberOfClusters        = 0,  ///< number of clusters per track
+    kNumberOfChamberHit      = 6,  ///< number of fired chambers per track
+    kChi2PerDof              = 12, ///< normalized chi2
+    kChi2PerDofVsNClusters   = 18, ///< normalized chi2 versus number of clusters
+    kChi2PerDofVsNChamberHit = 24, ///< normalized chi2 versus number of fired chambers
+    kP                       = 30, ///< momentum
+    kPt                      = 36, ///< transverse momentum
+    kEta                     = 42, ///< pseudo-rapidity
+    kPhi                     = 48, ///< phi angle
+    kDCA                     = 54, ///< DCA
+    kPDCA23                  = 60, ///< P*DCA in 2-3 deg
+    kPDCA310                 = 66, ///< P*DCA in 3-10 deg
+    kRAbs                    = 72, ///< R at the end of the absorber
+    kNhistTrack              = 78  ///< number of histograms at track level
+  };
+  
+  enum histoIndexAdd {
+    kNumberOfTracks,             ///< number of tracks
+    kNumberOfAdditionalTracks,   ///< number of additional tracks
+    kNumberOfClustersMC,         ///< number of clusters per MC track
+    kFractionOfMatchedClusters,  ///< fraction of matched clusters in matched tracks
+    kFractionOfConnectedClusters ///< fraction of connected clusters in fake tracks
   };
   
   enum histo2Index {
-    // physics quantities
-    k2Mass,   ///< invariant mass of the pair
-    k2MassM,  ///< invariant mass of matched-matched pairs
-    k2MassF1, ///< invariant mass of matched-fake pairs
-    k2MassF2, ///< invariant mass of fake-fake pairs
-    k2P,      ///< momentum of the pair
-    k2PM,     ///< momentum of matched-matched pairs
-    k2PF1,    ///< momentum of matched-fake pairs
-    k2PF2,    ///< momentum of fake-fake pairs
-    k2Pt,     ///< transverse momentum of pair
-    k2PtM,    ///< transverse momentum of matched-matched pairs
-    k2PtF1,   ///< transverse momentum of matched-fake pairs
-    k2PtF2,   ///< transverse momentum of fake-fake pairs
-    k2Y,      ///< rapidity of pair
-    k2YM,     ///< rapidity of matched-matched pairs
-    k2YF1,    ///< rapidity of matched-fake pairs
-    k2YF2,    ///< rapidity of fake-fake pairs
-    k2Eta,    ///< pseudo-rapidity of pair
-    k2EtaM,   ///< pseudo-rapidity of matched-matched pairs
-    k2EtaF1,  ///< pseudo-rapidity of matched-fake pairs
-    k2EtaF2,  ///< pseudo-rapidity of fake-fake pairs
-    k2Phi,    ///< phi angle of pair
-    k2PhiM,   ///< phi angle of matched-matched pairs
-    k2PhiF1,  ///< phi angle of matched-fake pairs
-    k2PhiF2,  ///< phi angle of fake-fake pairs
+    k2Mass     = 0,  ///< invariant mass
+    k2P        = 4,  ///< momentum
+    k2Pt       = 8,  ///< transverse momentum
+    k2Y        = 12, ///< rapidity
+    k2Eta      = 16, ///< pseudo-rapidity
+    k2Phi      = 20, ///< phi angle
+    kNhistPair = 24  ///< number of histograms at pair level
   };
   
   TObjArray* fList;     //!< list of output histograms about single tracks
-  TObjArray* fList2;     //!< list of output histograms about track pairs
+  TObjArray* fList2;    //!< list of output histograms about track pairs
   TObjArray* fCanvases; //!< List of canvases summarizing the results
   
   AliCounterCollection* fTrackCounters;        //!< global counters of tracks
@@ -152,17 +161,37 @@ private:
   AliCounterCollection* fEventCounters;        //!< counters of events
   AliCounterCollection* fPairCounters;         //!< global counters of track pairs
   
-  TString  fCurrentFileName;      //!< current input file name
-  UInt_t   fRequestedStationMask; //!< sigma cut to associate clusters with TrackRefs
-  Bool_t   fRequest2ChInSameSt45; //!< 2 fired chambers requested in the same station (4 or 5) or not
-  Double_t fSigmaCut;             //!< mask of requested stations
-  Bool_t   fUseLabel;             ///< match reconstructed and simulated tracks by using the MC labels or by position
-  Bool_t   fMatchTrig;            ///< fill histograms with tracks matched with trigger only
-  Bool_t   fApplyAccCut;          ///< fill histograms with tracks passing the acceptance cuts (Rabs, eta) only
-  TString  fRecoParamLocation;    ///< ocdb path toward the reconstruction parameters
-  
-  ClassDef(AliAnalysisTaskMuonFakes, 2); // fake muon analysis
+  TString  fCurrentFileName;         //!< current input file name
+  UInt_t   fRequestedStationMask;    //!< mask of requested stations
+  Bool_t   fRequest2ChInSameSt45;    //!< 2 fired chambers requested in the same station (4 or 5) or not
+  Double_t fSigmaCut;                //!< sigma cut to associate clusters with TrackRefs
+  Int_t    fNEvents;                 //!< number of processed events
+  Bool_t   fShowProgressBar;         ///< show the progression bar
+  Bool_t   fUseLabel;                ///< match reconstructed and simulated tracks by using the MC labels or by position
+  Bool_t   fCombineMCId;             ///< combine reconstructed/simulated track matching by MC labels and by position
+  Double_t fExternalSigmaCut;        ///< sigma cut to associate clusters with TrackRefs (instead of using recoParam)
+  Bool_t   fMatchTrig;               ///< fill histograms with tracks matched with trigger only
+  Bool_t   fApplyAccCut;             ///< fill histograms with tracks passing the acceptance cuts (Rabs, eta) only
+  Double_t fChi2Cut;                 ///< cut on normalized chi2
+  Double_t fPtCut;                   ///< cut on minimum pt
+  TString  fRecoParamLocation;       ///< ocdb path toward the reconstruction parameters
+  Bool_t   fDecayAsFake;             ///< considere decays as fake tracks or not
+  Bool_t   fPrintDecayChain;         ///< print labels of connected particles and ancestors when looking for decays
+  Bool_t   fDisableDetailedCounters; ///< disable the recording of event/file of problematic tracks
+  
+  AliMuonTrackCuts* fMuonTrackCuts; ///< cuts to select tracks to be considered
+  
+  ClassDef(AliAnalysisTaskMuonFakes, 3); // fake muon analysis
 };
 
+
+//________________________________________________________________________
+inline void AliAnalysisTaskMuonFakes::SetMuonTrackCuts(AliMuonTrackCuts &trackCuts)
+{
+  /// set standard cuts to select tracks to be considered
+  delete fMuonTrackCuts;
+  fMuonTrackCuts = new AliMuonTrackCuts(trackCuts);
+}
+
 #endif