Updates for the centralized automatic QA (Ionut)
[u/mrichter/AliRoot.git] / PWGPP / AliAnalysisTaskFilteredTree.cxx
index a2db075..716c41c 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
+/*
+   Class to process/filter reconstruction information from ESD, ESD friends, MC and provide them for later reprocessing
+   Filtering schema - low pt part is downscaled - to have flat pt specatra of selected topologies (tracks and V0s)
+   Downscaling schema is controlled by downscaling factors
+   Usage: 
+     1.) Filtering on Lego train
+     2.) expert QA for tracking (resolution efficnecy)
+     3.) pt reoslution studies using V0s 
+     4.) dEdx calibration using V0s
+     5.) pt resolution and dEdx studies using cosmic
+     +
+     6.) Info used for later raw data OFFLINE triggering  (highPt, V0, laser, cosmic, high dEdx)
+
+   Exported trees (with full objects and dereived variables):
+   1.) "highPt"     - filtered trees with esd tracks, derived variables(propagated tracks), optional MC info +optional space points
+   2.) "V0s" -      - filtered trees with selected V0s (rough KF chi2 cut), KF particle and corresponding esd tracks + optionla space points
+   3.) "Laser"      - dump laser tracks with space points if exests 
+   4.) "CosmicTree" - cosmic track candidate (random or triggered) + esdTracks(up/down)+ optional points
+   5.) "dEdx"       - tree with high dEdx tpc tracks
+*/
+
 #include "iostream"
 #include "TSystem.h"
-
 #include <TPDGCode.h>
 #include <TDatabasePDG.h>
 
@@ -91,8 +111,10 @@ ClassImp(AliAnalysisTaskFilteredTree)
   , fCentralityEstimator(0)
   , fLowPtTrackDownscaligF(0)
   , fLowPtV0DownscaligF(0)
+  , fFriendDownscaling(-3.)   
   , fProcessAll(kFALSE)
   , fProcessCosmics(kFALSE)
+  , fProcessITSTPCmatchOut(kFALSE)  // swittch to process ITS/TPC standalone tracks
   , fHighPtTree(0)
   , fV0Tree(0)
   , fdEdxTree(0)
@@ -108,7 +130,7 @@ ClassImp(AliAnalysisTaskFilteredTree)
   , fPtResCentPtTPC(0)
   , fPtResCentPtTPCc(0)
   , fPtResCentPtTPCITS(0)
-  , fDummyFriendTrack(0)
+  , fCurrentFileName("")
   , fDummyTrack(0)
 {
   // Constructor
@@ -126,16 +148,9 @@ ClassImp(AliAnalysisTaskFilteredTree)
 //_____________________________________________________________________________
 AliAnalysisTaskFilteredTree::~AliAnalysisTaskFilteredTree()
 {
-  //the output trees not to be deleted in case of proof analysis
-  //Bool_t deleteTrees=kTRUE;
-  //if ((AliAnalysisManager::GetAnalysisManager()))
-  //{
-  //  if (AliAnalysisManager::GetAnalysisManager()->GetAnalysisType() == 
-  //           AliAnalysisManager::kProofAnalysis)
-  //    deleteTrees=kFALSE;
-  //}
-  //if (deleteTrees) delete fTreeSRedirector;
-
+  //
+  // Destructor
+  //
   delete fFilteredTreeEventCuts;
   delete fFilteredTreeAcceptanceCuts;
   delete fFilteredTreeRecAcceptanceCuts;
@@ -145,15 +160,16 @@ AliAnalysisTaskFilteredTree::~AliAnalysisTaskFilteredTree()
 //____________________________________________________________________________
 Bool_t AliAnalysisTaskFilteredTree::Notify()
 {
+  //
+  //
   static Int_t count = 0;
   count++;
   TTree *chain = (TChain*)GetInputData(0);
-  if(chain)
-  {
+  if(chain){
     Printf("Processing %d. file: %s", count, chain->GetCurrentFile()->GetName());
-  }
-
-return kTRUE;
+  }  
+  fCurrentFileName=chain->GetCurrentFile()->GetName();
+  return kTRUE;
 }
 
 //_____________________________________________________________________________
@@ -176,14 +192,7 @@ void AliAnalysisTaskFilteredTree::UserCreateOutputObjects()
   fMCEffTree = ((*fTreeSRedirector)<<"MCEffTree").GetTree();
   fCosmicPairsTree = ((*fTreeSRedirector)<<"CosmicPairs").GetTree();
 
-  if (!fDummyFriendTrack)
-  {
-    fDummyFriendTrack=new AliESDfriendTrack();
-    fDummyFriendTrack->SetTrackPointArray(new AliTrackPointArray(164));
-    printf("just made a new dummy friend track!");
-  }
-  if (!fDummyTrack)
-  {
+  if (!fDummyTrack)  {
     fDummyTrack=new AliESDtrack();
   }
 
@@ -290,45 +299,42 @@ void AliAnalysisTaskFilteredTree::UserExec(Option_t *)
     Printf("ERROR: ESD event not available");
     return;
   }
-
-  //// MC event
-  //if(fUseMCInfo) {
-  //  fMC = MCEvent();
-  //  if (!fMC) {
-  //    Printf("ERROR: MC event not available");
-  //    return;
-  //  }
-  //}
-
   //if MC info available - use it.
   fMC = MCEvent();
-
   if(fUseESDfriends) {
     //fESDfriend = dynamic_cast<AliESDfriend*>(fESD->FindListObject("AliESDfriend"));
     fESDfriend = ESDfriend();
-
     if(!fESDfriend) {
       Printf("ERROR: ESD friends not available");
     }
   }
+  AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
+  if (!inputHandler){
+    return;
+  }
 
   //if set, use the environment variables to set the downscaling factors
   //AliAnalysisTaskFilteredTree_fLowPtTrackDownscaligF
   //AliAnalysisTaskFilteredTree_fLowPtV0DownscaligF
+  //AliAnalysisTaskFilteredTree_fFriendDownscaling
   TString env;
   env = gSystem->Getenv("AliAnalysisTaskFilteredTree_fLowPtTrackDownscaligF");
-  if (!env.IsNull())
-  {
+  if (!env.IsNull()){
     fLowPtTrackDownscaligF=env.Atof();
     AliInfo(Form("fLowPtTrackDownscaligF=%f",fLowPtTrackDownscaligF));
   }
   env = gSystem->Getenv("AliAnalysisTaskFilteredTree_fLowPtV0DownscaligF");
-  if (!env.IsNull())
-  {
+  if (!env.IsNull()){
     fLowPtV0DownscaligF=env.Atof();
     AliInfo(Form("fLowPtV0DownscaligF=%f",fLowPtTrackDownscaligF));
   }
-
+  env = gSystem->Getenv("AliAnalysisTaskFilteredTree_fFriendDownscaling");
+  if (!env.IsNull()){
+    fFriendDownscaling=env.Atof();
+    AliInfo(Form(" fFriendDownscaling=%f",fFriendDownscaling));
+  }
+  //
+  //
   //
   if(fProcessAll) { 
     ProcessAll(fESD,fMC,fESDfriend); // all track stages and MC
@@ -336,48 +342,21 @@ void AliAnalysisTaskFilteredTree::UserExec(Option_t *)
   else {
     Process(fESD,fMC,fESDfriend);    // only global and TPC tracks
   }
-
   //
   ProcessV0(fESD,fMC,fESDfriend);
   ProcessLaser(fESD,fMC,fESDfriend);
   ProcessdEdx(fESD,fMC,fESDfriend);
-
   if (fProcessCosmics) { ProcessCosmics(fESD,fESDfriend); }
   if(fMC) { ProcessMCEff(fESD,fMC,fESDfriend);}
-  printf("processed event %i\n", Entry());
+  if (fProcessITSTPCmatchOut) ProcessITSTPCmatchOut(fESD, fESDfriend);
+  printf("processed event %d\n", Int_t(Entry()));
 }
 
 //_____________________________________________________________________________
 void AliAnalysisTaskFilteredTree::ProcessCosmics(AliESDEvent *const event, AliESDfriend* esdFriend)
 {
   //
-  // Select real events with high-pT tracks 
-  //
-  if(!event) {
-    AliDebug(AliLog::kError, "event not available");
-    return;
-  }
-
-  // 
-  AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
-
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
-
-
-  // check for cosmic pairs
-  //
-  // find cosmic pairs trigger by random trigger
+  // Find cosmic pairs (triggered or random) 
   //
   //
   AliESDVertex *vertexSPD =  (AliESDVertex *)event->GetPrimaryVertexSPD();
@@ -387,12 +366,9 @@ void AliAnalysisTaskFilteredTree::ProcessCosmics(AliESDEvent *const event, AliES
   const Double_t kMinNcl=50;
   const Double_t kMaxDelta[5]={2,600,0.02,0.02,0.1};
   Int_t ntracks=event->GetNumberOfTracks(); 
-  //  Float_t dcaTPC[2]={0,0};
-  // Float_t covTPC[3]={0,0,0};
-
   UInt_t specie = event->GetEventSpecie();  // skip laser events
   if (specie==AliRecoParam::kCalib) return;
-
+  Int_t ntracksFriend = esdFriend ? esdFriend->GetNumberOfTracks() : 0;
 
 
   for (Int_t itrack0=0;itrack0<ntracks;itrack0++) {
@@ -413,10 +389,11 @@ void AliAnalysisTaskFilteredTree::ProcessCosmics(AliESDEvent *const event, AliES
     //if (TMath::Abs(dcaTPC[1])<kMaxDelta[0]*2) continue;
     //    const AliExternalTrackParam * trackIn0 = track0->GetInnerParam();
     AliESDfriendTrack* friendTrack0=NULL;
-    if (esdFriend) {if (!esdFriend->TestSkipBit()) friendTrack0 = esdFriend->GetTrack(itrack0);} //this guy can be NULL
-    //Bool_t newFriendTrack0=kFALSE;
-    //if (!friendTrack0) {friendTrack0=new AliESDfriendTrack(); newFriendTrack0=kTRUE;}
-    if (!friendTrack0) {friendTrack0=fDummyFriendTrack;}
+    if (esdFriend &&!esdFriend->TestSkipBit()){
+      if (itrack0<ntracksFriend){
+       friendTrack0 = esdFriend->GetTrack(itrack0);
+      } //this guy can be NULL
+    }
 
     for (Int_t itrack1=itrack0+1;itrack1<ntracks;itrack1++) {
       AliESDtrack *track1 = event->GetTrack(itrack1);
@@ -443,20 +420,16 @@ void AliAnalysisTaskFilteredTree::ProcessCosmics(AliESDEvent *const event, AliES
       if (TMath::Abs(TMath::Abs(track0->GetAlpha()-track1->GetAlpha())-TMath::Pi())>kMaxDelta[2]) isPair=kFALSE;
       //delta with correct sign
       /*
-         TCut cut0="abs(t1.fP[0]+t0.fP[0])<2"
-         TCut cut3="abs(t1.fP[3]+t0.fP[3])<0.02"
-         TCut cut4="abs(t1.fP[4]+t0.fP[4])<0.2"
-         */
+       TCut cut0="abs(t1.fP[0]+t0.fP[0])<2"
+       TCut cut3="abs(t1.fP[3]+t0.fP[3])<0.02"
+       TCut cut4="abs(t1.fP[4]+t0.fP[4])<0.2"
+      */
       if  (TMath::Abs(par0[0]+par1[0])>kMaxDelta[0]) isPair=kFALSE; //delta y   opposite sign
       if  (TMath::Abs(par0[3]+par1[3])>kMaxDelta[3]) isPair=kFALSE; //delta tgl opposite sign
       if  (TMath::Abs(AliTracker::GetBz())>1 && TMath::Abs(par0[4]+par1[4])>kMaxDelta[4]) isPair=kFALSE; //delta 1/pt opposite sign
       if (!isPair) continue;
       TString filename(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
       Int_t eventNumber = event->GetEventNumberInFile(); 
-      //Bool_t hasFriend = kFALSE;
-      //Bool_t hasITS=(track0->GetNcls(0)+track1->GetNcls(0)>4);
-      //printf("DUMPHPTCosmic:%s|%f|%d|%d|%d\n",filename.Data(),(TMath::Min(track0->Pt(),track1->Pt())), eventNumber,hasFriend,hasITS);
-      //      const AliExternalTrackParam * trackIn1 = track1->GetInnerParam();      
       //
       //               
       Int_t ntracksSPD = vertexSPD->GetNContributors();
@@ -473,58 +446,61 @@ void AliAnalysisTaskFilteredTree::ProcessCosmics(AliESDEvent *const event, AliES
       ULong64_t periodID     = (ULong64_t)event->GetPeriodNumber();
       ULong64_t gid          = ((periodID << 36) | (orbitID << 12) | bunchCrossID); 
       
-      //
-      // Dump to the tree 
-      // vertex
-      // TPC-ITS tracks
-      //
-
-      //fCosmicPairsTree->Branch("fileName",&fileName,32000,0);
-      //fCosmicPairsTree->Branch("runNumber",&runNumber,"runNumber/I");
-      //fCosmicPairsTree->Branch("timeStamp",&timeStamp,"timeStamp/I");
-      //fCosmicPairsTree->Branch("eventNumber",&eventNumber,"eventNumber/I");
-      //fCosmicPairsTree->Branch("triggerMask",&triggerMask,32000,0);
-      //fCosmicPairsTree->Branch("triggerClass",&triggerClass,32000,0);
-      //fCosmicPairsTree->Branch("magField",&magField,"magField/F");
-      //fCosmicPairsTree->Branch("ntracksSPD",&ntracksSPD,"ntracksSPD/I");
-      //fCosmicPairsTree->Branch("ntracksTPC",&ntracksTPC,"ntracksTPC/I");
-      //fCosmicPairsTree->Branch("vertexSPD",vertexSPD,32000,0);
-      //fCosmicPairsTree->Branch("vertexTPC",vertexTPC,32000,0);
-      //fCosmicPairsTree->Branch("track0",track0,32000,0);
-      //fCosmicPairsTree->Branch("track1",track1,32000,0);
-      //
-      //fCosmicPairsTree->Fill();
 
       AliESDfriendTrack* friendTrack1=NULL;
-      if (esdFriend) {if (!esdFriend->TestSkipBit()) friendTrack1 = esdFriend->GetTrack(itrack1);} //this guy can be NULL
-      //Bool_t newFriendTrack1=kFALSE;
-      //if (!friendTrack1) {friendTrack1=new AliESDfriendTrack(); newFriendTrack1=kTRUE;}
-      if (!friendTrack1) {friendTrack1=fDummyFriendTrack;}
+      if (esdFriend &&!esdFriend->TestSkipBit()){
+       if (itrack1<ntracksFriend){
+         friendTrack1 = esdFriend->GetTrack(itrack1);
+       } //this guy can be NULL
+      }
 
+      //
+      AliESDfriendTrack *friendTrackStore0=friendTrack0;    // store friend track0 for later processing
+      AliESDfriendTrack *friendTrackStore1=friendTrack1;    // store friend track1 for later processing
+      if (fFriendDownscaling>=1){  // downscaling number of friend tracks
+       if (gRandom->Rndm()>1./fFriendDownscaling){
+         friendTrackStore0 = 0;
+         friendTrackStore1 = 0;
+       }
+      }
+      if (fFriendDownscaling<=0){
+       if (((*fTreeSRedirector)<<"CosmicPairs").GetTree()){
+         TTree * tree = ((*fTreeSRedirector)<<"CosmicPairs").GetTree();
+         if (tree){
+           Double_t sizeAll=tree->GetZipBytes();
+           TBranch * br= tree->GetBranch("friendTrack0.fPoints");
+           Double_t sizeFriend=(br!=NULL)?br->GetZipBytes():0;
+           br= tree->GetBranch("friendTrack0.fCalibContainer");
+           if (br) sizeFriend+=br->GetZipBytes();
+           if (sizeFriend*TMath::Abs(fFriendDownscaling)>sizeAll) {
+             friendTrackStore0=0;
+             friendTrackStore1=0;
+           }
+         }
+       }
+      }
       if(!fFillTree) return;
       if(!fTreeSRedirector) return;
       (*fTreeSRedirector)<<"CosmicPairs"<<
-        "gid="<<gid<<
-        "fileName.="<<&fileName<<         // file name
-        "runNumber="<<runNumber<<              //  run number      
-        "evtTimeStamp="<<timeStamp<<            //  time stamp of event
-        "evtNumberInFile="<<eventNumber<<          //  event number        
-        "trigger="<<triggerMask<<      //  trigger
-        "triggerClass="<<&triggerClass<<      //  trigger
-        "Bz="<<magField<<             //  magnetic field
+        "gid="<<gid<<                         // global id of track
+        "fileName.="<<&fCurrentFileName<<     // file name
+        "runNumber="<<runNumber<<             // run number        
+        "evtTimeStamp="<<timeStamp<<          // time stamp of event
+        "evtNumberInFile="<<eventNumber<<     // event number      
+        "trigger="<<triggerMask<<             // trigger mask
+        "triggerClass="<<&triggerClass<<      // trigger class
+        "Bz="<<magField<<                     // magnetic field
         //
-        "multSPD="<<ntracksSPD<<
-        "multTPC="<<ntracksTPC<<
-        "vertSPD.="<<vertexSPD<<         //primary vertex -SPD
-        "vertTPC.="<<vertexTPC<<         //primary vertex -TPC
-        "t0.="<<track0<<              //track0
-        "t1.="<<track1<<              //track1
-        "friendTrack0.="<<friendTrack0<<
-        "friendTrack1.="<<friendTrack1<<
+        "multSPD="<<ntracksSPD<<              // event ultiplicity
+        "multTPC="<<ntracksTPC<<              //  
+        "vertSPD.="<<vertexSPD<<              // primary vertex -SPD
+        "vertTPC.="<<vertexTPC<<              // primary vertex -TPC
+        "t0.="<<track0<<                      // first half of comsic trak
+        "t1.="<<track1<<                      // second half of cosmic track
+        "friendTrack0.="<<friendTrackStore0<< // friend information first track  + points
+        "friendTrack1.="<<friendTrackStore1<< // frined information first track  + points 
         "\n";      
-      //if (newFriendTrack1) {delete friendTrack1; friendTrack1=NULL;}
     }
-    //if (newFriendTrack0) {delete friendTrack0; friendTrack0=NULL;}
   }
 }
 
@@ -535,10 +511,6 @@ void AliAnalysisTaskFilteredTree::Process(AliESDEvent *const esdEvent, AliMCEven
   //
   // Select real events with high-pT tracks 
   //
-  if(!esdEvent) {
-    AliDebug(AliLog::kError, "esdEvent not available");
-    return;
-  }
 
   // get selection cuts
   AliFilteredTreeEventCuts *evtCuts = GetEventCuts(); 
@@ -557,20 +529,6 @@ void AliAnalysisTaskFilteredTree::Process(AliESDEvent *const esdEvent, AliMCEven
 
   // 
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
-
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
-
   // trigger
   if(evtCuts->IsTriggerRequired())  
   {
@@ -721,30 +679,11 @@ void AliAnalysisTaskFilteredTree::Process(AliESDEvent *const esdEvent, AliMCEven
       // TPC-ITS tracks
       //
       TObjString triggerClass = esdEvent->GetFiredTriggerClasses().Data();
-
-      //fHighPtTree->Branch("fileName",&fileName,32000,0);
-      //fHighPtTree->Branch("runNumber",&runNumber,"runNumber/I");
-      //fHighPtTree->Branch("evtTimeStamp",&evtTimeStamp,"evtTimeStamp/I");
-      //fHighPtTree->Branch("evtNumberInFile",&evtNumberInFile,"evtNumberInFile/I");
-      //fHighPtTree->Branch("triggerClass",&triggerClass,32000,0);
-      //fHighPtTree->Branch("Bz",&bz,"Bz/F");
-      //fHighPtTree->Branch("vtxESD",vtxESD,32000,0);
-      //fHighPtTree->Branch("IRtot",&ir1,"IRtot/I");
-      //fHighPtTree->Branch("IRint2",&ir2,"IRint2/I");
-      //fHighPtTree->Branch("mult",&mult,"mult/I");
-      //fHighPtTree->Branch("esdTrack",track,32000,0);
-      //fHighPtTree->Branch("centralityF",&centralityF,"centralityF/F");
-
-      //fHighPtTree->Fill();
-
-      //Double_t vtxX=vtxESD->GetX();
-      //Double_t vtxY=vtxESD->GetY();
-      //Double_t vtxZ=vtxESD->GetZ();
       if(!fFillTree) return;
       if(!fTreeSRedirector) return;
       (*fTreeSRedirector)<<"highPt"<<
         "gid="<<gid<<
-        "fileName.="<<&fileName<<            
+        "fileName.="<<&fCurrentFileName<<            
         "runNumber="<<runNumber<<
         "evtTimeStamp="<<evtTimeStamp<<
         "evtNumberInFile="<<evtNumberInFile<<
@@ -752,9 +691,6 @@ void AliAnalysisTaskFilteredTree::Process(AliESDEvent *const esdEvent, AliMCEven
         "Bz="<<bz<<                           //  magnetic field
         "vtxESD.="<<vtxESD<<
         "ntracksESD="<<ntracks<<              // number of tracks in the ESD
-        //  "vtxESDx="<<vtxX<<
-        //  "vtxESDy="<<vtxY<<
-        //  "vtxESDz="<<vtxZ<<
         "IRtot="<<ir1<<                      // interaction record history info
         "IRint2="<<ir2<<
         "mult="<<mult<<                      // multiplicity of tracks pointing to the primary vertex
@@ -773,66 +709,46 @@ void AliAnalysisTaskFilteredTree::Process(AliESDEvent *const esdEvent, AliMCEven
 void AliAnalysisTaskFilteredTree::ProcessLaser(AliESDEvent *const esdEvent, AliMCEvent * const /*mcEvent*/, AliESDfriend *const esdFriend)
 {
   //
-  // Process laser events
+  // Process laser events -> dump tracks and clusters  to the special tree
   //
-  if(!esdEvent) {
-    AliDebug(AliLog::kError, "esdEvent not available");
-    return;
-  }
-
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
-
+  const Double_t kMinPt = 5; 
   if(!fFillTree) return;
   if(!fTreeSRedirector) return;
-
-  // laser events 
   const AliESDHeader* esdHeader = esdEvent->GetHeader();
-  if(esdHeader && esdHeader->GetEventSpecie()==AliRecoParam::kCalib) 
-  {
+  if(esdHeader && esdHeader->GetEventSpecie()==AliRecoParam::kCalib) {
     Int_t countLaserTracks = 0;
     Int_t runNumber = esdEvent->GetRunNumber();
     Int_t evtTimeStamp = esdEvent->GetTimeStamp();
     Int_t evtNumberInFile = esdEvent->GetEventNumberInFile();
     Float_t bz = esdEvent->GetMagneticField();
-    TObjString triggerClass = esdEvent->GetFiredTriggerClasses().Data();
-    
+    TObjString triggerClass = esdEvent->GetFiredTriggerClasses().Data();    
     // Global event id calculation using orbitID, bunchCrossingID and periodID
     ULong64_t orbitID      = (ULong64_t)esdEvent->GetOrbitNumber();
     ULong64_t bunchCrossID = (ULong64_t)esdEvent->GetBunchCrossNumber();
     ULong64_t periodID     = (ULong64_t)esdEvent->GetPeriodNumber();
     ULong64_t gid          = ((periodID << 36) | (orbitID << 12) | bunchCrossID); 
-
-    for (Int_t iTrack = 0; iTrack < esdEvent->GetNumberOfTracks(); iTrack++)
-    {
+    for (Int_t iTrack = 0; iTrack < esdEvent->GetNumberOfTracks(); iTrack++){
       AliESDtrack *track = esdEvent->GetTrack(iTrack);
       if(!track) continue;
-
-      if(track->GetTPCInnerParam()) countLaserTracks++;
-      
+      if(track->GetTPCInnerParam()) countLaserTracks++;      
       AliESDfriendTrack* friendTrack=NULL;
-      if (esdFriend) {if (!esdFriend->TestSkipBit()) friendTrack = esdFriend->GetTrack(iTrack);} //this guy can be NULL
-      //Bool_t newFriendTrack=kFALSE;
-      //if (!friendTrack) {friendTrack=new AliESDfriendTrack(); newFriendTrack=kTRUE;}
-      if (!friendTrack) {friendTrack=fDummyFriendTrack;}
-      
+      // suppress beam background and CE random reacks
+      if (track->GetInnerParam()->Pt()<kMinPt) continue;
+      Bool_t skipTrack=gRandom->Rndm()>1/(1+TMath::Abs(fFriendDownscaling));
+      if (skipTrack) continue;
+      if (esdFriend) {if (!esdFriend->TestSkipBit()) friendTrack = esdFriend->GetTrack(iTrack);} //this guy can be NULL      
       (*fTreeSRedirector)<<"Laser"<<
-        "gid="<<gid<<
-        "fileName.="<<&fileName<<
+        "gid="<<gid<<                          // global identifier of event
+        "fileName.="<<&fCurrentFileName<<              //
         "runNumber="<<runNumber<<
         "evtTimeStamp="<<evtTimeStamp<<
         "evtNumberInFile="<<evtNumberInFile<<
-        "triggerClass="<<&triggerClass<<      //  trigger
-        "Bz="<<bz<<
-        "multTPCtracks="<<countLaserTracks<<
-        "friendTrack.="<<friendTrack<<
+        "triggerClass="<<&triggerClass<<        //  trigger
+        "Bz="<<bz<<                             //  magnetic field
+        "multTPCtracks="<<countLaserTracks<<    //  multiplicity of tracks
+       "track.="<<track<<                      //  track parameters
+        "friendTrack.="<<friendTrack<<          //  friend track information
         "\n";
-      //if (newFriendTrack) {delete friendTrack; friendTrack=NULL;}
     }
   }
 }
@@ -854,12 +770,6 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
   //   track references at ITSin, TPCin; InnerParam at first TPC track reference, 
   //   particle ID, mother ID, production mechanism ...
   // 
-
-  if(!esdEvent) {
-    AliDebug(AliLog::kError, "esdEvent not available");
-    return;
-  }
-
   // get selection cuts
   AliFilteredTreeEventCuts *evtCuts = GetEventCuts(); 
   AliFilteredTreeAcceptanceCuts *accCuts = GetAcceptanceCuts(); 
@@ -877,19 +787,7 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
 
   // 
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
 
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
 
   // trigger
   if(evtCuts->IsTriggerRequired())  
@@ -1407,7 +1305,26 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
 
         //assign the dummy objects if needed
         if (!track) {track=fDummyTrack;}
-        if (!friendTrack) {friendTrack=fDummyFriendTrack;}
+       AliESDfriendTrack *friendTrackStore=friendTrack;    // store friend track for later processing
+       if (fFriendDownscaling>=1){  // downscaling number of friend tracks
+         friendTrackStore = (gRandom->Rndm()<1./fFriendDownscaling)? friendTrack:0;
+       }
+       if (fFriendDownscaling<=0){
+         if (((*fTreeSRedirector)<<"highPt").GetTree()){
+           TTree * tree = ((*fTreeSRedirector)<<"highPt").GetTree();
+           if (tree){
+             Double_t sizeAll=tree->GetZipBytes();
+             TBranch * br= tree->GetBranch("friendTrack.fPoints");
+             Double_t sizeFriend=(br!=NULL)?br->GetZipBytes():0;
+             br= tree->GetBranch("friendTrack.fCalibContainer");
+             if (br) sizeFriend+=br->GetZipBytes();
+             if (sizeFriend*TMath::Abs(fFriendDownscaling)>sizeAll) friendTrackStore=0;
+           }
+         }
+       }
+
+
+       //        if (!friendTrackStore && fFriendDownscaling<=1) {friendTrack=fDummyFriendTrack;}
         if (!vtxESD) {vtxESD=&dummyvtxESD;}
         if (mcEvent)
         {
@@ -1420,32 +1337,6 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
           if (!particleITS) {particleITS=&dummyparticle;}
           if (!particleMotherITS) {particleMotherITS=&dummyparticle;}
         }
-        //the following are guaranteed to exist:
-        //if (!tpcInnerC) {tpcInnerC=&dummyexternaltrackparam;}
-        //if (!trackInnerC) {trackInnerC=&dummyexternaltrackparam;}
-        //if (!trackInnerC2) {trackInnerC2=&dummyexternaltrackparam;}
-        //if (!outerITSc) {outerITSc=&dummyexternaltrackparam;}
-        //if (!trackInnerC3) {trackInnerC3=&dummyexternaltrackparam;}
-        /////////////////////////
-
-        //Double_t vtxX=vtxESD->GetX();
-        //Double_t vtxY=vtxESD->GetY();
-        //Double_t vtxZ=vtxESD->GetZ();
-
-        //AliESDVertex* pvtxESD = (AliESDVertex*)vtxESD->Clone();
-        //AliESDtrack* ptrack=(AliESDtrack*)track->Clone();
-        //AliExternalTrackParam* ptpcInnerC = (AliExternalTrackParam*)tpcInnerC->Clone();
-        //AliExternalTrackParam* ptrackInnerC = (AliExternalTrackParam*)trackInnerC->Clone();
-        //AliExternalTrackParam* ptrackInnerC2 = (AliExternalTrackParam*)trackInnerC2->Clone();
-        //AliExternalTrackParam* pouterITSc = (AliExternalTrackParam*)outerITSc->Clone();
-        //AliExternalTrackParam* ptrackInnerC3 = (AliExternalTrackParam*)trackInnerC3->Clone();
-        //AliESDVertex* pvtxESD = new AliESDVertex(*vtxESD);
-        //AliESDtrack* ptrack= new AliESDtrack(*track);
-        //AliExternalTrackParam* ptpcInnerC = new AliExternalTrackParam(*tpcInnerC);
-        //AliExternalTrackParam* ptrackInnerC = new AliExternalTrackParam(*trackInnerC);
-        //AliExternalTrackParam* ptrackInnerC2 = new AliExternalTrackParam(*trackInnerC2);
-        //AliExternalTrackParam* pouterITSc =  new AliExternalTrackParam(*outerITSc);
-        //AliExternalTrackParam* ptrackInnerC3 = new AliExternalTrackParam(*trackInnerC3);
 
         Int_t ntracks = esdEvent->GetNumberOfTracks();
 
@@ -1458,34 +1349,16 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
         // fill histograms
         FillHistograms(track, tpcInnerC, centralityF, (Double_t)chi2(0,0));
 
-        if(fTreeSRedirector && dumpToTree && fFillTree) 
-        {
-
-          //if (friendTrack)
-          //{
-          //  const AliTrackPointArray* array = friendTrack->GetTrackPointArray();
-          //  if (!array) {printf("we have a friend, but the ponits are empty\n"); continue;}
-          //  if (friendTrack==fDummyFriendTrack) printf("using the dummy friend track\n");
-          //  cout<<array->GetX()[0]<<" "<<array->GetX()[2]<<endl;
-          //}
-          //else
-          //{
-          //  printf("no friend track\n");
-          //}
-
-
+        if(fTreeSRedirector && dumpToTree && fFillTree) {
           (*fTreeSRedirector)<<"highPt"<<
             "gid="<<gid<<
-            "fileName.="<<&fileName<<                // name of the chunk file (hopefully full)
+            "fileName.="<<&fCurrentFileName<<                // name of the chunk file (hopefully full)
             "runNumber="<<runNumber<<                // runNumber
             "evtTimeStamp="<<evtTimeStamp<<          // time stamp of event (in seconds)
             "evtNumberInFile="<<evtNumberInFile<<    // event number
             "triggerClass="<<&triggerClass<<         // trigger class as a string
             "Bz="<<bz<<                              // solenoid magnetic field in the z direction (in kGaus)
             "vtxESD.="<<vtxESD<<                    // vertexer ESD tracks (can be biased by TPC pileup tracks)
-            //"vtxESDx="<<vtxX<<
-            //"vtxESDy="<<vtxY<<
-            //"vtxESDz="<<vtxZ<<
             "IRtot="<<ir1<<                         // interaction record (trigger) counters - coutner 1
             "IRint2="<<ir2<<                        // interaction record (trigger) coutners - counter 2
             "mult="<<mult<<                         // multiplicity of tracks pointing to the primary vertex
@@ -1499,7 +1372,8 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
             "ntracksITS="<<ntracksITS<<               // total number of the ITS tracks which were refitted
             //
             "esdTrack.="<<track<<                  // esdTrack as used in the physical analysis
-            "friendTrack.="<<friendTrack<<      // esdFriendTrack associated to the esdTrack
+           //            "friendTrack.="<<friendTrack<<      // esdFriendTrack associated to the esdTrack
+            "friendTrack.="<<friendTrackStore<<      // esdFriendTrack associated to the esdTrack
             "extTPCInnerC.="<<tpcInnerC<<          // ??? 
             "extInnerParamC.="<<trackInnerC<<      // ???
             "extInnerParam.="<<trackInnerC2<<      // ???
@@ -1509,8 +1383,7 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
             "chi2InnerC="<<chi2trackC(0,0)<<        // chi2s  of tracks TPCinner to the combined
             "chi2OuterITS="<<chi2OuterITS(0,0)<<    // chi2s  of tracks TPC at inner wall to the ITSout
             "centralityF="<<centralityF;
-          if (mcEvent)
-          {
+          if (mcEvent){
             static AliTrackReference refDummy;
             if (!refITS) refITS = &refDummy;
             if (!refTRD) refTRD = &refDummy;
@@ -1558,8 +1431,7 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
           AliInfo("writing tree highPt");
           (*fTreeSRedirector)<<"highPt"<<"\n";
         }
-        AliSysInfo::AddStamp("filteringTask",iTrack,numberOfTracks,numberOfFriendTracks,(friendTrack=fDummyFriendTrack)?0:1);
-
+        AliSysInfo::AddStamp("filteringTask",iTrack,numberOfTracks,numberOfFriendTracks,(friendTrackStore)?0:1);
         delete tpcInnerC;
         delete trackInnerC;
         delete trackInnerC2;
@@ -1567,7 +1439,6 @@ void AliAnalysisTaskFilteredTree::ProcessAll(AliESDEvent *const esdEvent, AliMCE
         delete trackInnerC3;
       }
   }
-
 }
 
 
@@ -1577,12 +1448,6 @@ void AliAnalysisTaskFilteredTree::ProcessMCEff(AliESDEvent *const esdEvent, AliM
   //
   // Fill tree for efficiency studies MC only
   AliInfo("we start!");
-
-  if(!esdEvent) {
-    AliDebug(AliLog::kError, "esdEvent not available");
-    return;
-  }
-
   if(!mcEvent) {
     AliDebug(AliLog::kError, "mcEvent not available");
     return;
@@ -1605,26 +1470,13 @@ void AliAnalysisTaskFilteredTree::ProcessMCEff(AliESDEvent *const esdEvent, AliM
 
   // 
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
 
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
 
   // trigger
   if(evtCuts->IsTriggerRequired())  
   {
     // always MB
     isEventTriggered = inputHandler->IsEventSelected() & AliVEvent::kMB;
-
     physicsSelection = static_cast<AliPhysicsSelection*> (inputHandler->GetEventSelection());
     if(!physicsSelection) return;
 
@@ -1830,7 +1682,7 @@ void AliAnalysisTaskFilteredTree::ProcessMCEff(AliESDEvent *const esdEvent, AliM
       //
       if(fTreeSRedirector && fFillTree) {
         (*fTreeSRedirector)<<"MCEffTree"<<
-          "fileName.="<<&fileName<<
+          "fileName.="<<&fCurrentFileName<<
           "triggerClass.="<<&triggerClass<<
           "runNumber="<<runNumber<<
           "evtTimeStamp="<<evtTimeStamp<<
@@ -1915,19 +1767,6 @@ void AliAnalysisTaskFilteredTree::ProcessV0(AliESDEvent *const esdEvent, AliMCEv
 
   // 
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
-
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
 
   // trigger
   if(evtCuts->IsTriggerRequired())  
@@ -2001,24 +1840,48 @@ void AliAnalysisTaskFilteredTree::ProcessV0(AliESDEvent *const esdEvent, AliMCEv
       if (!track1) continue;
       AliESDfriendTrack* friendTrack0=NULL;
       AliESDfriendTrack* friendTrack1=NULL;
-      if (esdFriend) 
-      {
-        if (!esdFriend->TestSkipBit())
-        {
-          friendTrack0 = esdFriend->GetTrack(v0->GetIndex(0)); //this guy can be NULL
-          friendTrack1 = esdFriend->GetTrack(v0->GetIndex(1)); //this guy can be NULL
+      if (esdFriend)       {
+        if (!esdFriend->TestSkipBit()){
+         Int_t ntracksFriend = esdFriend->GetNumberOfTracks();
+         if (v0->GetIndex(0)<ntracksFriend){
+           friendTrack0 = esdFriend->GetTrack(v0->GetIndex(0)); //this guy can be NULL
+         }
+         if (v0->GetIndex(1)<ntracksFriend){
+           friendTrack1 = esdFriend->GetTrack(v0->GetIndex(1)); //this guy can be NULL
+         }
         }
       }
-      //Bool_t newFriendTrack0=kFALSE;
-      //Bool_t newFriendTrack1=kFALSE;
-      //if (!friendTrack0) {friendTrack0=new AliESDfriendTrack(); newFriendTrack0=kTRUE;}
-      //if (!friendTrack1) {friendTrack1=new AliESDfriendTrack(); newFriendTrack1=kTRUE;}
-      if (!friendTrack0) {friendTrack0=fDummyFriendTrack;}
-      if (!friendTrack1) {friendTrack1=fDummyFriendTrack;}
       if (track0->GetSign()<0) {
         track1 = esdEvent->GetTrack(v0->GetIndex(0));
         track0 = esdEvent->GetTrack(v0->GetIndex(1));
       }
+
+      //
+      AliESDfriendTrack *friendTrackStore0=friendTrack0;    // store friend track0 for later processing
+      AliESDfriendTrack *friendTrackStore1=friendTrack1;    // store friend track1 for later processing
+      if (fFriendDownscaling>=1){  // downscaling number of friend tracks
+       if (gRandom->Rndm()>1./fFriendDownscaling){
+         friendTrackStore0 = 0;
+         friendTrackStore1 = 0;
+       }
+      }
+      if (fFriendDownscaling<=0){
+       if (((*fTreeSRedirector)<<"V0s").GetTree()){
+         TTree * tree = ((*fTreeSRedirector)<<"V0s").GetTree();
+         if (tree){
+           Double_t sizeAll=tree->GetZipBytes();
+           TBranch * br= tree->GetBranch("friendTrack0.fPoints");
+           Double_t sizeFriend=(br!=NULL)?br->GetZipBytes():0;
+           br= tree->GetBranch("friendTrack0.fCalibContainer");
+           if (br) sizeFriend+=br->GetZipBytes();
+           if (sizeFriend*TMath::Abs(fFriendDownscaling)>sizeAll) {
+             friendTrackStore0=0;
+             friendTrackStore1=0;
+           }
+         }
+       }
+      }
+
       //
       Bool_t isDownscaled = IsV0Downscaled(v0);
       if (isDownscaled) continue;
@@ -2030,26 +1893,24 @@ void AliAnalysisTaskFilteredTree::ProcessV0(AliESDEvent *const esdEvent, AliMCEv
       if(!fFillTree) return;
       if(!fTreeSRedirector) return;
       (*fTreeSRedirector)<<"V0s"<<
-        "gid="<<gid<<
-        "isDownscaled="<<isDownscaled<<
+        "gid="<<gid<<                         //  global id of event
+        "isDownscaled="<<isDownscaled<<       //  
         "triggerClass="<<&triggerClass<<      //  trigger
-        "Bz="<<bz<<
-        "fileName.="<<&fileName<<
-        "runNumber="<<run<<
-        "evtTimeStamp="<<time<<
-        "evtNumberInFile="<<evNr<<
-        "type="<<type<<
+        "Bz="<<bz<<                           //
+        "fileName.="<<&fCurrentFileName<<     //  full path - file name with ESD
+        "runNumber="<<run<<                   //
+        "evtTimeStamp="<<time<<               //  time stamp of event in secons
+        "evtNumberInFile="<<evNr<<            //  
+        "type="<<type<<                       // type of V0-
         "ntracks="<<ntracks<<
         "v0.="<<v0<<
         "kf.="<<&kfparticle<<
-        "track0.="<<track0<<
+        "track0.="<<track0<<                  // track
         "track1.="<<track1<<
-        "friendTrack0.="<<friendTrack0<<
-        "friendTrack1.="<<friendTrack1<<
+        "friendTrack0.="<<friendTrackStore0<<
+        "friendTrack1.="<<friendTrackStore1<<
         "centralityF="<<centralityF<<
         "\n";
-      //if (newFriendTrack0) {delete friendTrack0;}
-      //if (newFriendTrack1) {delete friendTrack1;}
     }
   }
 }
@@ -2075,13 +1936,6 @@ void AliAnalysisTaskFilteredTree::ProcessdEdx(AliESDEvent *const esdEvent, AliMC
     return;
   }
 
-  // get file name
-  TTree *chain = (TChain*)GetInputData(0);
-  if(!chain) { 
-    Printf("ERROR: Could not receive input chain");
-    return;
-  }
-  TObjString fileName(chain->GetCurrentFile()->GetName());
 
   // trigger
   Bool_t isEventTriggered = kTRUE;
@@ -2090,11 +1944,6 @@ void AliAnalysisTaskFilteredTree::ProcessdEdx(AliESDEvent *const esdEvent, AliMC
 
   // 
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
-  if (!inputHandler)
-  {
-    Printf("ERROR: Could not receive input handler");
-    return;
-  }
 
   if(evtCuts->IsTriggerRequired())  
   {
@@ -2155,10 +2004,13 @@ void AliAnalysisTaskFilteredTree::ProcessdEdx(AliESDEvent *const esdEvent, AliMC
       AliESDtrack *track = esdEvent->GetTrack(iTrack);
       if(!track) continue;
       AliESDfriendTrack* friendTrack=NULL;
-      if (esdFriend) {if (!esdFriend->TestSkipBit()) friendTrack = esdFriend->GetTrack(iTrack);} //this guy can be NULL
-      //Bool_t newFriendTrack=kFALSE;
-      //if (!friendTrack) {friendTrack=new AliESDfriendTrack(); newFriendTrack=kTRUE;}
-      if (!friendTrack) {friendTrack=fDummyFriendTrack;}
+      if (esdFriend && !esdFriend->TestSkipBit()) {
+       Int_t ntracksFriend = esdFriend->GetNumberOfTracks();
+       if (iTrack<ntracksFriend){
+         friendTrack = esdFriend->GetTrack(iTrack);
+       } //this guy can be NULL        
+      }
+      
       if(track->Charge()==0) continue;
       if(!esdTrackCuts->AcceptTrack(track)) continue;
       if(!accCuts->AcceptTrack(track)) continue;
@@ -2168,20 +2020,19 @@ void AliAnalysisTaskFilteredTree::ProcessdEdx(AliESDEvent *const esdEvent, AliMC
 
       if(!fFillTree) return;
       if(!fTreeSRedirector) return;
-      (*fTreeSRedirector)<<"dEdx"<<
-        "gid="<<gid<<
-        "fileName.="<<&fileName<<
+      (*fTreeSRedirector)<<"dEdx"<<           // high dEdx tree
+        "gid="<<gid<<                         // global id
+        "fileName.="<<&fCurrentFileName<<     // file name
         "runNumber="<<runNumber<<
         "evtTimeStamp="<<evtTimeStamp<<
         "evtNumberInFile="<<evtNumberInFile<<
         "triggerClass="<<&triggerClass<<      //  trigger
         "Bz="<<bz<<
-        "vtxESD.="<<vtxESD<<
+        "vtxESD.="<<vtxESD<<                  // 
         "mult="<<mult<<
         "esdTrack.="<<track<<
         "friendTrack.="<<friendTrack<<
         "\n";
-      //if (newFriendTrack) delete friendTrack;
     }
   }
 }
@@ -2219,8 +2070,6 @@ Int_t   AliAnalysisTaskFilteredTree::GetKFParticle(AliESDv0 *const v0, AliESDEve
   if (TMath::Abs(track1->GetTgl())>1) return 0;
   if ((track0->GetTPCClusterInfo(2,1))<100) return 0;
   if ((track1->GetTPCClusterInfo(2,1))<100) return 0;
-  //if ((track0->GetITSclusters(0))<2) return 0;
-  //if ((track1->GetITSclusters(0))<2) return 0; 
   Float_t pos0[2]={0}, cov0[3]={0};
   Float_t pos1[2]={0}, cov1[3]={0};
   track0->GetImpactParameters(pos0,cov0);
@@ -2528,67 +2377,6 @@ void AliAnalysisTaskFilteredTree::FinishTaskOutput()
   // Called one at the end 
   // locally on working node
   //
-
-  //// must be deleted to store trees
-  //if(fTreeSRedirector)  delete fTreeSRedirector; fTreeSRedirector=0;
-
-  //// open temporary file and copy trees to the ouptut container
-
-  //TChain* chain = 0;
-  ////
-  //chain = new TChain("highPt");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fHighPtTree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fHighPtTree) fHighPtTree->Print();
-
-  ////
-  //chain = new TChain("V0s");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fV0Tree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fV0Tree) fV0Tree->Print();
-
-  ////
-  //chain = new TChain("dEdx");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fdEdxTree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fdEdxTree) fdEdxTree->Print();
-
-  ////
-  //chain = new TChain("Laser");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fLaserTree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fLaserTree) fLaserTree->Print();
-
-  ////
-  //chain = new TChain("MCEffTree");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fMCEffTree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fMCEffTree) fMCEffTree->Print();
-
-  ////
-  //chain = new TChain("CosmicPairs");
-  //if(chain) { 
-  //  chain->Add("jotwinow_Temp_Trees.root");
-  //  fCosmicPairsTree = chain->CopyTree("1");
-  //  delete chain; chain=0; 
-  //}
-  //if(fCosmicPairsTree) fCosmicPairsTree->Print();  
-
   Bool_t deleteTrees=kTRUE;
   if ((AliAnalysisManager::GetAnalysisManager()))
   {
@@ -2598,40 +2386,14 @@ void AliAnalysisTaskFilteredTree::FinishTaskOutput()
   }
   if (deleteTrees) delete fTreeSRedirector;
   fTreeSRedirector=NULL;
-
-  //OpenFile(1);
-
-  // Post output data.
-  //PostData(1, fHighPtTree);
-  //PostData(2, fV0Tree);
-  //PostData(3, fdEdxTree);
-  //PostData(4, fLaserTree);
-  //PostData(5, fMCEffTree);
-  //PostData(6, fCosmicPairsTree);
 }
 
 //_____________________________________________________________________________
 void AliAnalysisTaskFilteredTree::Terminate(Option_t *) 
 {
+  //
   // Called one at the end 
-  /*
-     fOutputSummary = dynamic_cast<TTree*> (GetOutputData(1));
-     if(fOutputSummary) delete fOutputSummary; fOutputSummary=0;
-     TChain* chain = new TChain("highPt");
-     if(!chain) return;
-     chain->Add("jotwinow_HighPt_TrackAndV0_Trees.root");
-     TTree *tree = chain->CopyTree("1");
-     if (chain) { delete chain; chain=0; }
-     if(!tree) return;
-     tree->Print();
-     fOutputSummary = tree;
-
-     if (!fOutputSummary) {
-     Printf("ERROR: AliAnalysisTaskFilteredTree::Terminate(): Output data not avaiable %p \n", GetOutputData(1));
-     return;
-     }
-     */
-
+  //
 }
 
 //_____________________________________________________________________________
@@ -2755,3 +2517,205 @@ void AliAnalysisTaskFilteredTree::FillHistograms(AliESDtrack* const ptrack, AliE
     fPtResCentPtTPCc->Fill(ptpcInnerC->Pt(),centralityF,1./abs(ptpcInnerC->GetSigned1Pt())*TMath::Sqrt(ptpcInnerC->GetSigma1Pt2()));
   }
 }
+
+
+void AliAnalysisTaskFilteredTree::ProcessITSTPCmatchOut(AliESDEvent *const esdEvent, AliESDfriend *const esdFriend){
+  //
+  // Process ITS standalone tracks find match with closest TPC(or combined tracks) tracks 
+  // marian.ivanov@cern.ch
+  // 0.) Init variables
+  // 1.) GetTrack parameters at TPC inner wall
+  // 2.) Match closest TPC  track  (STANDALONE/global) - chi2 match criteria
+  //
+  // Logic to be used in reco:
+  // 1.) Find matching ITSalone->TPCalone
+  // 2.) if (!TPCalone.FindClose(TPCother))  TPCalone.Addopt(ITSalone)
+  // 3.) ff ((ITSalone.FindClose(Global)==0) CreateGlobaltrack
+  const Double_t radiusMatch=84.;    // redius to propagate
+  //
+  const Double_t dFastPhiCut=0.2;        // 6 sigma (200 MeV) fast angular cut
+  const Double_t dFastThetaCut=0.12;     // 6 sigma (200 MeV) fast angular cut
+  const Double_t dFastPosPhiCut=0.06;    // 6 sigma (200 MeV) fast angular cut
+  const Double_t dFastZCut=6;            // 6 sigma (200 MeV) fast  z difference cut
+  const Double_t dFastPtCut=2.;          // 6 sigma (200 MeV) fast 1/pt cut 
+  const Double_t chi2Cut=100;            // chi2 matching cut
+  //
+  if (!esdFriend) return;  // not ITS standalone track
+  if (esdFriend->TestSkipBit()) return; // friends tracks  not stored
+  Int_t ntracks=esdEvent->GetNumberOfTracks();
+  Float_t bz = esdEvent->GetMagneticField();
+  //
+  // 0.) Get parameters in reference radius TPC Inner wall
+  //
+  //
+  TMatrixD vecPosR0(ntracks,6);   // possition and  momentum estimate at reference radius  
+  TMatrixD vecMomR0(ntracks,6);   //
+  TMatrixD vecPosR1(ntracks,6);   // possition and  momentum estimate at reference radius TPC track  
+  TMatrixD vecMomR1(ntracks,6);   //
+  Double_t xyz[3], pxyz[3];      //
+  for (Int_t iTrack=0; iTrack<ntracks; iTrack++){
+    AliESDtrack *track = esdEvent->GetTrack(iTrack);   
+    if(!track) continue;
+    if (track->GetInnerParam()){
+      const AliExternalTrackParam *trackTPC=track->GetInnerParam();
+      trackTPC->GetXYZAt(radiusMatch,bz,xyz);
+      trackTPC->GetPxPyPzAt(radiusMatch,bz,pxyz);
+      for (Int_t i=0; i<3; i++){
+       vecPosR1(iTrack,i)=xyz[i];
+       vecMomR1(iTrack,i)=pxyz[i];
+      }
+      vecPosR1(iTrack,3)= TMath::ATan2(xyz[1],xyz[0]);    // phi pos angle
+      vecMomR1(iTrack,3)= TMath::ATan2(pxyz[1],pxyz[0]);  // phi mom angle
+      vecMomR1(iTrack,4)= trackTPC->GetSigned1Pt();;    
+      vecMomR1(iTrack,5)= trackTPC->GetTgl();;    
+    }
+    AliESDfriendTrack* friendTrack=esdFriend->GetTrack(iTrack);
+    if(!friendTrack) continue;
+    if (friendTrack->GetITSOut()){
+      const AliExternalTrackParam *trackITS=friendTrack->GetITSOut();
+      trackITS->GetXYZAt(radiusMatch,bz,xyz);
+      trackITS->GetPxPyPzAt(radiusMatch,bz,pxyz);
+      for (Int_t i=0; i<3; i++){
+       vecPosR0(iTrack,i)=xyz[i];
+       vecMomR0(iTrack,i)=pxyz[i];
+      }
+      vecPosR0(iTrack,3)= TMath::ATan2(xyz[1],xyz[0]);
+      vecMomR0(iTrack,3)= TMath::ATan2(pxyz[1],pxyz[0]);
+      vecMomR0(iTrack,4)= trackITS->GetSigned1Pt();;    
+      vecMomR0(iTrack,5)= trackITS->GetTgl();;    
+    }
+  }
+  //  
+  // 1.) Find closest matching tracks, between the ITS standalone track 
+  // and  the all other tracks
+  //  a.) caltegory  - All
+  //  b.) category   - without ITS 
+  //      
+  //
+  Int_t ntracksPropagated=0;
+  AliExternalTrackParam extTrackDummy;
+  AliESDtrack           esdTrackDummy; 
+  AliExternalTrackParam itsAtTPC;
+  AliExternalTrackParam itsAtITSTPC;
+  for (Int_t iTrack0=0; iTrack0<ntracks; iTrack0++){
+    AliESDtrack *track0 = esdEvent->GetTrack(iTrack0);   
+    if(!track0) continue;
+    if (track0->IsOn(AliVTrack::kTPCin)) continue;
+    AliESDfriendTrack* friendTrack0=esdFriend->GetTrack(iTrack0); 
+    if (!friendTrack0) continue;
+    //if (!track0->IsOn(AliVTrack::kITSpureSA)) continue;
+    //if (!friendTrack0->GetITSOut()) continue;  // is there flag for ITS standalone?
+    ntracksPropagated++;
+    // 
+    // 2.) find clostest TPCtrack
+    //     a.) all tracks
+    Double_t minChi2All=10000000;
+    Double_t minChi2TPC=10000000;
+    Double_t minChi2TPCITS=10000000;
+    Int_t indexAll=-1;
+    Int_t indexTPC=-1;
+    Int_t indexTPCITS=-1;
+    Int_t ncandidates0=0; // n candidates - rough cut
+    Int_t ncandidates1=0; // n candidates - rough + chi2 cut
+    itsAtTPC=*(friendTrack0->GetITSOut());
+    itsAtITSTPC=*(friendTrack0->GetITSOut());
+    for (Int_t iTrack1=0; iTrack1<ntracks; iTrack1++){
+      AliESDtrack *track1 = esdEvent->GetTrack(iTrack1);   
+      if(!track1) continue;
+      if (!track1->IsOn(AliVTrack::kTPCin)) continue;
+      // fast checks
+      //
+      if (TMath::Abs(vecPosR1(iTrack1,2)-vecPosR0(iTrack0,2))>dFastZCut) continue;
+      if (TMath::Abs(vecPosR1(iTrack1,3)-vecPosR0(iTrack0,3))>dFastPosPhiCut) continue;
+      if (TMath::Abs(vecMomR1(iTrack1,3)-vecMomR0(iTrack0,3))>dFastPhiCut) continue;
+      if (TMath::Abs(vecMomR1(iTrack1,5)-vecMomR0(iTrack0,5))>dFastThetaCut) continue;
+      if (TMath::Abs(vecMomR1(iTrack1,4)-vecMomR0(iTrack0,4))>dFastPtCut) continue;
+      ncandidates0++;
+      //
+      const AliExternalTrackParam * param1= track1->GetInnerParam();
+      if (!friendTrack0->GetITSOut()) continue;
+      AliExternalTrackParam outerITS = *(friendTrack0->GetITSOut());
+      if (!outerITS.Rotate(param1->GetAlpha())) continue;
+      if (!outerITS.PropagateTo(param1->GetX(),bz)) continue; // assume track close to the TPC inner wall
+      Double_t chi2 =  outerITS.GetPredictedChi2(param1);
+      if (chi2>chi2Cut) continue;
+      ncandidates1++;
+      if (chi2<minChi2All){
+       minChi2All=chi2;
+       indexAll=iTrack1;
+      }
+      if (chi2<minChi2TPC && track1->IsOn(AliVTrack::kITSin)==0){
+       minChi2TPC=chi2;
+       indexTPC=iTrack1;
+       itsAtTPC=outerITS;
+      }
+      if (chi2<minChi2TPCITS && track1->IsOn(AliVTrack::kITSin)){
+       minChi2TPCITS=chi2;
+       indexTPCITS=iTrack1;
+       itsAtITSTPC=outerITS;
+      }
+    }
+    //
+    AliESDtrack * trackAll= (indexAll>=0)? esdEvent->GetTrack(indexAll):&esdTrackDummy;
+    AliESDtrack * trackTPC= (indexTPC>=0)? esdEvent->GetTrack(indexTPC):&esdTrackDummy;
+    AliESDtrack * trackTPCITS= (indexTPCITS>=0)? esdEvent->GetTrack(indexTPCITS):&esdTrackDummy;
+    (*fTreeSRedirector)<<"itsTPC"<<
+      "indexAll="<<indexAll<<          // index of closest track (chi2)
+      "indexTPC="<<indexTPC<<          // index of closest TPCalone tracks
+      "indexTPCITS="<<indexTPCITS<<    // index of closest cobined tracks
+      "ncandidates0="<<ncandidates0<<  // number of candidates
+      "ncandidates1="<<ncandidates1<<
+      //
+      "chi2All="<<minChi2All<<         // chi2 of closest  tracks
+      "chi2TPC="<<minChi2TPC<<         
+      "chi2TPCITS="<<minChi2TPCITS<<
+      //
+      "track0.="<<track0<<             // ITS standalone tracks
+      "trackAll.="<<trackAll<<         // Closets other track
+      "trackTPC.="<<trackTPC<<         // Closest TPC only track
+      "trackTPCITS.="<<trackTPCITS<<   // closest combined track
+      //
+      "itsAtTPC.="<<&itsAtTPC<<        // ITS track parameters at the TPC alone track  frame
+      "itsAtITSTPC.="<<&itsAtITSTPC<<  // ITS track parameters at the TPC combeined track  frame
+      "\n"; 
+  }
+}
+
+void AliAnalysisTaskFilteredTree::ProcessTrackMatch(AliESDEvent *const /*esdEvent*/, AliESDfriend *const /*esdFriend*/){
+/*
+    Use TPC standalone, ITS standalone and combined tracks to categorize/resp. recover track information.
+
+    Track categories:
+       -TPC+ITS
+       -TPC only 
+       -ITS only
+    Topology categories:
+       -Nice isolated tracks with full information 
+       -Overlapped tracks - Refit and sign them
+       -Multiple found (check overlap factor) - Merge and sign
+       -Charge particle (kink) decays - Change of direction - Sign them) 
+    Info:
+       -Array  of indexes of closest tracks in each individual category
+       -Chi2  distance to the closest tracks at reference radius of TPCin
+       -Overlap factors  - fraction of shared clusters or missing  region
+       -Chi2 distance at DCA
+    Information matrix:   
+       -matrix closest tracks from each categories
+       -characterization - chi2, index,chi2,  overlap ratio
+    
+    Decissions:
+       0.) Kink decay or catastophic multiple scaterring 
+           (combining all track categories)
+              - small chi2 at the DCA
+              - significantly large deflection angle
+              - Combinatorial algorithm - to decrease CPU time restriction of investigation to tracks with small DCA at  refernce radius
+
+       1.) if (TPConly && !(TPC+ITS) && ITSonly match ) {
+             if (!kink) TPCOnly.addoptITS
+             if (kink) TPConly sign
+           }
+
+       2.) Overlap tracks - Refit with doUnfold
+
+*/
+}