]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCcalibTracksGain.cxx
Fix to restore functionality.
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibTracksGain.cxx
index ae158897dcf1a8accaac900941a0c42ca61e46aa..e453180a77a93a01de716bbae0fdf5db44cdc926 100644 (file)
  **************************************************************************/
 
 ////////////////////////////////////////////////////////////////////////////
+//
+//
+//  Gain calibration using tracks
+//
+//  The main goal:
+//    1.) Inner TPC gain alignement - (parabolic) parameterization (inside of one sector) 
+//    2.) Angular and z-position correction (parabolic) parameterization 
+//    3.) Sector gain alignment  
+//   
+//  Following histograms are accumulated
+//    a.) Simple 1D histograms  per chamber  
+//    b.) Profile histograms per chamber - local x dependence    
+//    c.) 2D Profile histograms  - local x - fi dependence
+//
+//  To get the gain map - the simple solution - use the histograms - is not enough
+//  The resulting mean amplitude map depends strongly on the track topology
+//  These dependence can be reduced, taking into account angular effect, and diffusion effect 
+//  Using proper fit modeles
+//
+//     
+//
 //                                                                        
 //       === Calibration class for gain calibration using tracks ===
 //
 //             the fitters after loading this object from file.
 //             (This will be gone for a new ROOT version > v5-17-05)
 //                                                                        
+//
+//    In order to debug some numerical algorithm all data data which are used for
+//    fitters can be stored in the debug streamers. In case of fitting roblems the 
+//    errors and tendencies can be checked.
+//
+//    Debug Streamers:
+//      
+// 
+//
+//
+//
 ////////////////////////////////////////////////////////////////////////////
 
+/*
+  .x ~/UliStyle.C
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libSTAT");
+  gSystem->Load("libTPCcalib");
+
+  TFile fcalib("CalibObjects.root");
+  TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib");
+  AliTPCcalibTracksGain * gain = ( AliTPCcalibTracksGain *)array->FindObject("calibTracksGain");
+
+  //
+  // Angular and drift correction
+  //
+  AliTPCClusterParam *param = new AliTPCClusterParam;param->SetInstance(param);
+  gain->UpdateClusterParam(param);
+  TF2 fdrty("fdrty","AliTPCClusterParam::SQnorm(0,0,x,y,0)",0,1,0,1)
+
+  //
+  // Make visual Tree - compare with Kr calibration
+  // 
+  AliTPCCalPad * gain010 = gain->CreateFitCalPad(0,kTRUE,0); gain010->SetName("CGain010");
+  AliTPCCalPad * gain110 = gain->CreateFitCalPad(1,kTRUE,0); gain110->SetName("CGain110");
+  AliTPCCalPad * gain210 = gain->CreateFitCalPad(2,kTRUE,0); gain210->SetName("CGain210");
+  TFile fkr("/u/miranov/GainMap.root");
+  AliTPCCalPad *gainKr = fkr.Get("GainMap"); fkr->SetName("KrGain");
+  //
+  AliTPCPreprocessorOnline * preprocesor = new AliTPCPreprocessorOnline;
+  preprocesor->AddComponent(gain010);
+  preprocesor->AddComponent(gain110);
+  preprocesor->AddComponent(gain210);
+  preprocesor->AddComponent(gainKr);
+  preprocesor->DumpToFile("cosmicGain.root");
+  //
+  //
+  //
+  // Simple session using the debug streamers
+  //
+
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
+  gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+")
+  AliXRDPROOFtoolkit tool;   
+
+  TChain * chain0 = tool.MakeChain("gain.txt","dEdx",0,1000000);
+  TChain * chain1 = tool.MakeChain("gain.txt","Track",0,1000000);
+  TChain * chain2 = tool.MakeChain("gain.txt","TrackG",0,1000000);
+  chain0->Lookup();
+  chain1->Lookup();
+  chain2->Lookup();
+
+  chain2->SetAlias("k1","1/0.855");
+  chain2->SetAlias("k0","1/0.9928");
+  chain2->SetAlias("k2","1/1.152");
+  
+*/
+
+
+
+#include "AliTPCcalibTracksGain.h"
+
+
 #include <TPDGCode.h>
 #include <TStyle.h>
 #include "TSystem.h"
 #include "AliTPCClusterParam.h"
 #include "AliTrackPointArray.h"
 #include "TCint.h"
-#include "AliTPCcalibTracksGain.h"
 #include <TH1.h>
 #include <TH3F.h>
 #include <TLinearFitter.h>
 #include <TFile.h>
 #include <TCollection.h>
 #include <TIterator.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TProof.h>
+#include <TStatToolkit.h>
 
 //
 // AliRoot includes
 #include "AliTPCParamSR.h"
 #include "AliTPCCalROC.h"
 #include "AliTPCCalPad.h"
+#include "AliTPCClusterParam.h"
+#include "AliTPCcalibDB.h"
 //
 #include "AliTracker.h"
 #include "AliESD.h"
 #include "AliTPCclusterMI.h"
 #include "AliTPCcalibTracksCuts.h"
 #include "AliTPCFitPad.h"
+#include "TStatToolkit.h"
+#include "TString.h"
+#include "TCut.h"
 
-// REMOVE ALL OF THIS
+//
 #include <TTree.h>
 #include "AliESDEvent.h"
 
@@ -143,17 +243,36 @@ const char*    AliTPCcalibTracksGain::fgkDebugStreamFileName = "TPCCalibTracksGa
 AliTPCParamSR* AliTPCcalibTracksGain::fgTPCparam = new AliTPCParamSR();
 
 AliTPCcalibTracksGain::AliTPCcalibTracksGain() :
-   TNamed(),
-   fDebugCalPadRaw(0),
-   fDebugCalPadCorr(0),
-   fDebugStream(0),
-   fSimpleFitter(0),
-   fSqrtFitter(0),
-   fLogFitter(0),
-   fSingleSectorFitter(0),
-   fPrevIter(0),
-   fDebugStreamPrefix(0),
-   fCuts(0)
+  AliTPCcalibBase(),
+  fCuts(0),            // cuts that are used for sieving the tracks used for calibration
+  //
+  // Fitters
+  //
+  fSimpleFitter(0),         // simple fitter for short pads
+  fSqrtFitter(0),           // sqrt fitter for medium pads
+  fLogFitter(0),            // log fitter for long pads
+  
+  fFitter0M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter1M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter2M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter0T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter1T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter2T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  //
+  fDFitter0M(0),              // fitting of the atenuation, angular correction
+  fDFitter1M(0),              // fitting of the atenuation, angular correction
+  fDFitter2M(0),              // fitting of the atenuation, angular correction
+  fDFitter0T(0),              // fitting of the atenuation, angular correction
+  fDFitter1T(0),              // fitting of the atenuation, angular correction
+  fDFitter2T(0),              // fitting of the atenuation, angular correction
+  //
+  fSingleSectorFitter(0),   // just for debugging
+  //
+  // Counters
+  //
+  fTotalTracks(0),         // just for debugging
+  fAcceptedTracks(0)      // just for debugging
+
 {
    //
    // Default constructor.
@@ -161,21 +280,38 @@ AliTPCcalibTracksGain::AliTPCcalibTracksGain() :
 }
 
 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const AliTPCcalibTracksGain& obj) :
-   TNamed(obj)
+  AliTPCcalibBase(obj),
+  fCuts(obj.fCuts),            // cuts that are used for sieving the tracks used for calibration
+  //
+  // Fitters
+  //
+  fSimpleFitter(obj.fSimpleFitter),         // simple fitter for short pads
+  fSqrtFitter(obj.fSqrtFitter),           // sqrt fitter for medium pads
+  fLogFitter(obj.fLogFitter),            // log fitter for long pads
+  fFitter0M(obj.fFitter0M),
+  fFitter1M(obj.fFitter1M),
+  fFitter2M(obj.fFitter2M),
+  fFitter0T(obj.fFitter0T),
+  fFitter1T(obj.fFitter1T),
+  fFitter2T(obj.fFitter2T),
+  //
+  fDFitter0M(obj.fDFitter0M),
+  fDFitter1M(obj.fDFitter1M),
+  fDFitter2M(obj.fDFitter2M),
+  fDFitter0T(obj.fDFitter0T),
+  fDFitter1T(obj.fDFitter1T),
+  fDFitter2T(obj.fDFitter2T),
+  fSingleSectorFitter(obj.fSingleSectorFitter),   // just for debugging
+  //
+  // Counters
+  //
+  fTotalTracks(obj.fTotalTracks),         // just for debugging
+  fAcceptedTracks(obj.fAcceptedTracks)      // just for debugging
+
 {
    //
    // Copy constructor.
    //
-
-   fDebugCalPadRaw = new AliTPCCalPad(*(obj.fDebugCalPadRaw));
-   fDebugCalPadCorr = new AliTPCCalPad(*(obj.fDebugCalPadCorr));
-   fSimpleFitter = new AliTPCFitPad(*(obj.fSimpleFitter));
-   fSqrtFitter = new AliTPCFitPad(*(obj.fSqrtFitter));
-   fLogFitter = new AliTPCFitPad(*(obj.fLogFitter));
-   fSingleSectorFitter = new AliTPCFitPad(*(obj.fSingleSectorFitter));
-   fPrevIter = new AliTPCcalibTracksGain(*(obj.fPrevIter));
-   fDebugStreamPrefix = new TObjString(*(obj.fDebugStreamPrefix));
-   fCuts = new AliTPCcalibTracksCuts(*(obj.fCuts));
 }
 
 AliTPCcalibTracksGain& AliTPCcalibTracksGain::operator=(const AliTPCcalibTracksGain& rhs) {
@@ -185,84 +321,115 @@ AliTPCcalibTracksGain& AliTPCcalibTracksGain::operator=(const AliTPCcalibTracksG
 
    if (this != &rhs) {
       TNamed::operator=(rhs);
-      fDebugCalPadRaw = new AliTPCCalPad(*(rhs.fDebugCalPadRaw));
-      fDebugCalPadCorr = new AliTPCCalPad(*(rhs.fDebugCalPadCorr));
       fSimpleFitter = new AliTPCFitPad(*(rhs.fSimpleFitter));
       fSqrtFitter = new AliTPCFitPad(*(rhs.fSqrtFitter));
       fLogFitter = new AliTPCFitPad(*(rhs.fLogFitter));
       fSingleSectorFitter = new AliTPCFitPad(*(rhs.fSingleSectorFitter));
-      fPrevIter = new AliTPCcalibTracksGain(*(rhs.fPrevIter));
-      fDebugStreamPrefix = new TObjString(*(rhs.fDebugStreamPrefix));
       fCuts = new AliTPCcalibTracksCuts(*(rhs.fCuts));
    }
    return *this;
 }
 
-AliTPCcalibTracksGain::AliTPCcalibTracksGain(const char* name, const char* title, AliTPCcalibTracksCuts* cuts, TNamed* debugStreamPrefix, AliTPCcalibTracksGain* prevIter) :
-   TNamed(name, title),
-   fDebugCalPadRaw(0),
-   fDebugCalPadCorr(0),
-   fDebugStream(0),
-   fSimpleFitter(0),
-   fSqrtFitter(0),
-   fLogFitter(0),
-   fSingleSectorFitter(0),
-   fPrevIter(0),
-   fDebugStreamPrefix(0),
-   fCuts(0)
+AliTPCcalibTracksGain::AliTPCcalibTracksGain(const char* name, const char* title, AliTPCcalibTracksCuts* cuts) :
+  AliTPCcalibBase(),
+  fCuts(0),            // cuts that are used for sieving the tracks used for calibration
+  //
+  // Fitters
+  //
+  fSimpleFitter(0),         // simple fitter for short pads
+  fSqrtFitter(0),           // sqrt fitter for medium pads
+  fLogFitter(0),            // log fitter for long pads
+  fFitter0M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter1M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter2M(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter0T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter1T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  fFitter2T(0),              // fitting of the atenuation, angular correction, and mean chamber gain
+  //
+  fDFitter0M(0),              // fitting of the atenuation, angular correction
+  fDFitter1M(0),              // fitting of the atenuation, angular correction
+  fDFitter2M(0),              // fitting of the atenuation, angular correction
+  fDFitter0T(0),              // fitting of the atenuation, angular correction
+  fDFitter1T(0),              // fitting of the atenuation, angular correction
+  fDFitter2T(0),              // fitting of the atenuation, angular correction
+  fSingleSectorFitter(0),   // just for debugging
+  //
+  // Counters
+  //
+  fTotalTracks(0),         // just for debugging
+  fAcceptedTracks(0)      // just for debugging
+  
 {
    //
    // Constructor.
-   //
-   
-   G__SetCatchException(0);
-
+   //   
+   this->SetNameTitle(name, title);
    fCuts = cuts;
-   if (debugStreamPrefix) fDebugStreamPrefix = new TObjString(debugStreamPrefix->GetTitle());
-   fPrevIter = prevIter;
-
+   //
+   // Fitter initialization
+   //
    fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
    fSqrtFitter   = new AliTPCFitPad(8, "hyp7", "");
    fLogFitter    = new AliTPCFitPad(8, "hyp7", "");
    fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
-
-   // just for debugging
+   // 
+   fFitter0M      = new TLinearFitter(45,"hyp44");
+   fFitter1M      = new TLinearFitter(45,"hyp44");
+   fFitter2M      = new TLinearFitter(45,"hyp44");
+   fFitter0T      = new TLinearFitter(45,"hyp44");
+   fFitter1T      = new TLinearFitter(45,"hyp44");
+   fFitter2T      = new TLinearFitter(45,"hyp44");
+   //
+   fDFitter0M      = new TLinearFitter(10,"hyp9");
+   fDFitter1M      = new TLinearFitter(10,"hyp9");
+   fDFitter2M      = new TLinearFitter(10,"hyp9");
+   fDFitter0T      = new TLinearFitter(10,"hyp9");
+   fDFitter1T      = new TLinearFitter(10,"hyp9");
+   fDFitter2T      = new TLinearFitter(10,"hyp9");
+   //
+   // 
+   fFitter0M->StoreData(kFALSE);
+   fFitter1M->StoreData(kFALSE);
+   fFitter2M->StoreData(kFALSE);
+   fFitter0T->StoreData(kFALSE);
+   fFitter1T->StoreData(kFALSE);
+   fFitter2T->StoreData(kFALSE);   
+   //
+   fDFitter0M->StoreData(kFALSE);
+   fDFitter1M->StoreData(kFALSE);
+   fDFitter2M->StoreData(kFALSE);
+   fDFitter0T->StoreData(kFALSE);
+   fDFitter1T->StoreData(kFALSE);
+   fDFitter2T->StoreData(kFALSE);   
+   //
+   //
+   // just for debugging -counters
+   //
    fTotalTracks     = 0;
    fAcceptedTracks  = 0;
-   fDebugCalPadRaw  = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
-   fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
-   
    // this will be gone for the a new ROOT version > v5-17-05
    for (UInt_t i = 0; i < 36; i++) {
       fNShortClusters[i]  = 0;
       fNMediumClusters[i] = 0;
       fNLongClusters[i]   = 0;
    }
- }
+}
 
 AliTPCcalibTracksGain::~AliTPCcalibTracksGain() {
    //
    // Destructor.
    //
 
-   Info("Destructor","");
+   Info("Destructor",":");
    if (fSimpleFitter) delete fSimpleFitter;
    if (fSqrtFitter) delete fSqrtFitter;
    if (fLogFitter) delete fLogFitter;
    if (fSingleSectorFitter) delete fSingleSectorFitter;
 
+}
 
-   if (fDebugStream) {
-      //fDebugStream->GetFile()->Close();
-      printf("Deleting debug stream object\n");
-      delete fDebugStream;
-   }
 
-   if (fDebugStreamPrefix) delete fDebugStreamPrefix;
 
-   if (fDebugCalPadRaw) delete fDebugCalPadRaw;
-   if (fDebugCalPadCorr) delete fDebugCalPadCorr;
-}
 
 void AliTPCcalibTracksGain::Terminate(){
    //
@@ -271,77 +438,10 @@ void AliTPCcalibTracksGain::Terminate(){
    //
 
    Evaluate();
-   if (fDebugStream) {
-     delete fDebugStream;
-     fDebugStream = 0;
-   }
-
-   if (fDebugStreamPrefix) {
-      TString debugStreamPrefix = fDebugStreamPrefix->GetString();
-      TString destFile("");
-      destFile += debugStreamPrefix;
-      destFile += "/";
-      destFile += gSystem->HostName();
-      destFile += "_TPCCalibTracksGain.root";
-      if (debugStreamPrefix.BeginsWith("root://")) {
-         TFile::Cp("TPCCalibTracksGain.root", destFile.Data());
-      } else {
-         TString command("mv TPCCalibTracksGain.root ");
-         command += destFile;
-         gSystem->Exec(command.Data());
-      }
-   }
+   AliTPCcalibBase::Terminate();
 }
 
-void AliTPCcalibTracksGain::AddInfo(TChain* chain, char* debugStreamPrefix, char* prevIterFileName) {
-   // 
-   // Add some parameters to the chain.
-   // debugStreamPrefix: If specified, contains the location (either normal or xrootd directory)
-   //                    where the debug stream is moved (normal directory) or copied to (xrootd).
-   // prevIterFileName: If specified, contains an AliTPCcalibTracksGain object from a previous run
-   //                   for doing an iterative calibration procedure (right now unused).
-   // Note: The parameters are *not* added to this class, you need to do it later by retrieving
-   // the parameters from the chain and passing them to the constructor!
-   //
-
-   if (debugStreamPrefix) {
-      TNamed* objDebugStreamPrefix = new TNamed("debugStreamPrefix", debugStreamPrefix);
-      chain->GetUserInfo()->AddLast((TObject*)objDebugStreamPrefix);
-   }
-   
-   if (prevIterFileName) {
-      TFile paramFile(prevIterFileName);
-      if (paramFile.IsZombie()) {
-         printf("File %s not found. Continuing without previous iteration.\n", prevIterFileName);
-         return;
-      }
-      
-      AliTPCcalibTracksGain *prevIter = (AliTPCcalibTracksGain*)paramFile.Get("calibTracksGain");
-      if (prevIter) {
-         chain->GetUserInfo()->AddLast((TObject*)prevIter);
-      } else
-         printf("No calibTracksGain object found. Continuing without previous iteration.\n");
-   }
-}
 
-Bool_t AliTPCcalibTracksGain::AcceptTrack(AliTPCseed* track) {
-   //
-   // Decides whether to accept a track or not depending on track parameters and cuts
-   // contained as AliTPCcalibTracksCuts object fCuts.
-   // Tracks are discarded if the number of clusters is too low or the transverse
-   // momentum is too low.
-   // The corresponding cut values are specified in the fCuts member.
-   //
-   
-   if (track->GetNumberOfClusters() < fCuts->GetMinClusters()) return kFALSE;
-   //if ((TMath::Abs(track->GetY() / track->GetX()) > fCuts->GetEdgeYXCutNoise())
-   //   && (TMath::Abs(track->GetTgl()) < fCuts->GetEdgeThetaCutNoise())) return kFALSE;
-   //if (track->GetNumberOfClusters() / (track->GetNFoundable()+1.) < fCuts->GetMinRatio()) return kFALSE;
-   if (TMath::Abs(track->GetSigned1Pt()) > fCuts->GetMax1pt()) return kFALSE;
-   
-   //if (track->GetPt() < 50.) return kFALSE;
-   return kTRUE;
-}
 
 void AliTPCcalibTracksGain::Process(AliTPCseed* seed) {
    //
@@ -350,8 +450,36 @@ void AliTPCcalibTracksGain::Process(AliTPCseed* seed) {
    // is added.
    //
    
+
    fTotalTracks++;
-   if (!AcceptTrack(seed)) return;
+   if (!fCuts->AcceptTrack(seed)) return;
+   //
+   // reinint on proof
+   //   if (gProof){
+     static Bool_t doinit= kTRUE;
+     if (doinit){
+       fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
+       fSqrtFitter   = new AliTPCFitPad(8, "hyp7", "");
+       fLogFitter    = new AliTPCFitPad(8, "hyp7", "");
+       fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
+       // 
+       fFitter0M      = new TLinearFitter(45,"hyp44");
+       fFitter1M      = new TLinearFitter(45,"hyp44");
+       fFitter2M      = new TLinearFitter(45,"hyp44");
+       fFitter0T      = new TLinearFitter(45,"hyp44");
+       fFitter1T      = new TLinearFitter(45,"hyp44");
+       fFitter2T      = new TLinearFitter(45,"hyp44");
+       //
+       fDFitter0M      = new TLinearFitter(10,"hyp9");
+       fDFitter1M      = new TLinearFitter(10,"hyp9");
+       fDFitter2M      = new TLinearFitter(10,"hyp9");
+       fDFitter0T      = new TLinearFitter(10,"hyp9");
+       fDFitter1T      = new TLinearFitter(10,"hyp9");
+       fDFitter2T      = new TLinearFitter(10,"hyp9");
+       doinit=kFALSE;
+     }
+     //}
+
    fAcceptedTracks++;
    AddTrack(seed);
 }
@@ -373,44 +501,85 @@ Long64_t AliTPCcalibTracksGain::Merge(TCollection *list) {
    if (!fLogFitter)    fLogFitter    = new AliTPCFitPad(8, "hyp7", "");
    if (!fSingleSectorFitter) fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
 
-   // this will be gone for the a new ROOT version > v5-17-05
-   for (UInt_t i = 0; i < 36; i++) {
-      fNShortClusters[i]  = 0;
-      fNMediumClusters[i] = 0;
-      fNLongClusters[i]   = 0;
-   }
 
-   // just for debugging
-   if (fDebugCalPadRaw)  delete fDebugCalPadRaw;
-   if (fDebugCalPadCorr) delete fDebugCalPadCorr;
-   fDebugCalPadRaw  = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
-   fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
-   fTotalTracks     = 0;
-   fAcceptedTracks  = 0;
    
    TIterator* iter = list->MakeIterator();
    AliTPCcalibTracksGain* cal = 0;
    
    while ((cal = (AliTPCcalibTracksGain*)iter->Next())) {
       if (!cal->InheritsFrom(AliTPCcalibTracksGain::Class())) {
-         Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
+       //Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
          return -1;
       }
+      
       Add(cal);
    }
    return 0;
 }
 
+Float_t  AliTPCcalibTracksGain::GetGain(AliTPCclusterMI *cluster){
+  //
+  // get gain
+  //
+  Float_t gainPad= 1;
+  AliTPCCalPad * gainMap =  AliTPCcalibDB::Instance()->GetDedxGainFactor();
+  if (gainMap) {
+    AliTPCCalROC * roc = gainMap->GetCalROC(cluster->GetDetector());
+    gainPad  = roc->GetValue(cluster->GetRow(), TMath::Nint(cluster->GetPad()));
+  }
+  return gainPad;
+}
+
+Float_t   AliTPCcalibTracksGain::GetMaxNorm(AliTPCclusterMI * cluster, Float_t ky, Float_t kz){
+  //
+  // Get normalized amplituded if the gain map provided
+  //
+  AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
+  Float_t maxNorm =
+    parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), 
+                         cluster->GetTimeBin(),ky,kz,0.5,0.5,1.6);
+
+  return GetGain(cluster)*maxNorm;
+}
+
+
+Float_t   AliTPCcalibTracksGain::GetQNorm(AliTPCclusterMI * cluster,  Float_t ky, Float_t kz){
+  //
+  // Get normalized amplituded if the gain map provided
+  //
+  AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
+  Float_t totNorm = parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),                               cluster->GetTimeBin(),ky,kz,0.5,0.5,cluster->GetQ(),2.5,1.6);
+  return GetGain(cluster)*totNorm;
+}
+
+
+
 void AliTPCcalibTracksGain::Add(AliTPCcalibTracksGain* cal) {
    //
    // Adds another AliTPCcalibTracksGain object to this object.
    //
    
-   fSimpleFitter->Add(cal->fSimpleFitter);
-   fSqrtFitter->Add(cal->fSqrtFitter);
-   fLogFitter->Add(cal->fLogFitter);
-   fSingleSectorFitter->Add(cal->fSingleSectorFitter);
-
+  fSimpleFitter->Add(cal->fSimpleFitter);
+  fSqrtFitter->Add(cal->fSqrtFitter);
+  fLogFitter->Add(cal->fLogFitter);
+  fSingleSectorFitter->Add(cal->fSingleSectorFitter);
+  //
+  //
+  //
+  if (cal->fFitter0M->GetNpoints()>0) fFitter0M->Add(cal->fFitter0M);
+  if (cal->fFitter1M->GetNpoints()>0) fFitter1M->Add(cal->fFitter1M);
+  if (cal->fFitter2M->GetNpoints()>0) fFitter2M->Add(cal->fFitter2M);
+  if (cal->fFitter0T->GetNpoints()>0) fFitter0T->Add(cal->fFitter0T);
+  if (cal->fFitter1T->GetNpoints()>0) fFitter1T->Add(cal->fFitter1T);
+  if (cal->fFitter2T->GetNpoints()>0) fFitter2T->Add(cal->fFitter2T);
+  //
+  if (cal->fDFitter0M->GetNpoints()>0) fDFitter0M->Add(cal->fDFitter0M);
+  if (cal->fDFitter1M->GetNpoints()>0) fDFitter1M->Add(cal->fDFitter1M);
+  if (cal->fDFitter2M->GetNpoints()>0) fDFitter2M->Add(cal->fDFitter2M);
+  if (cal->fDFitter0T->GetNpoints()>0) fDFitter0T->Add(cal->fDFitter0T);
+  if (cal->fDFitter1T->GetNpoints()>0) fDFitter1T->Add(cal->fDFitter1T);
+  if (cal->fDFitter2T->GetNpoints()>0) fDFitter2T->Add(cal->fDFitter2T);
+   //
    // this will be gone for the a new ROOT version > v5-17-05
    for (UInt_t iSegment = 0; iSegment < 36; iSegment++) {
       fNShortClusters[iSegment] += cal->fNShortClusters[iSegment];
@@ -421,11 +590,7 @@ void AliTPCcalibTracksGain::Add(AliTPCcalibTracksGain* cal) {
    // just for debugging, remove me
    fTotalTracks += cal->fTotalTracks;
    fAcceptedTracks += cal->fAcceptedTracks;
-   fDebugCalPadRaw->Add(cal->fDebugCalPadRaw);
-   fDebugCalPadCorr->Add(cal->fDebugCalPadCorr);
 
-   // Let's see later what to do with fCuts, fDebugStream and fDebugStreamPrefix,
-   // we'll probably won't merge them.
 }
 
 void AliTPCcalibTracksGain::AddTrack(AliTPCseed* seed) {
@@ -434,13 +599,15 @@ void AliTPCcalibTracksGain::AddTrack(AliTPCseed* seed) {
    // See AddCluster(...) for more detail.
    //
    
-   if (!fDebugStream) fDebugStream = new TTreeSRedirector(fgkDebugStreamFileName);
-   DumpTrack(seed);
+   DumpTrack(seed);   
 }
    
-void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t momenta, Float_t mdedx, Int_t padType,
-            Float_t xcenter, TVectorD dedxQ, TVectorD dedxM, Float_t fraction, Float_t fraction2, Float_t dedge,
-            TVectorD parY, TVectorD parZ, TVectorD meanPos) {
+
+
+
+void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t /*momenta*/, Float_t/* mdedx*/, Int_t padType,
+                                      Float_t xcenter, TVectorD& dedxQ, TVectorD& /*dedxM*/, Float_t /*fraction*/, Float_t fraction2, Float_t dedge,
+                                      TVectorD& parY, TVectorD& parZ, TVectorD& meanPos) {
    //
    // Adds cluster to the appropriate fitter for later analysis.
    // The charge used for the fit is the maximum charge for this specific cluster or the
@@ -452,14 +619,38 @@ void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t momenta
    // gets the square root of the charge, and the log fitter gets fgkM*(1+q/fgkM), where q is the original charge
    // and fgkM==25.
    //
+  Float_t kedge     = 3;
+  Float_t kfraction = 0.7;
+  Int_t   kinorm    = 2;
+
+
+  // Where to put selection on threshold? 
+  // Defined by the Q/dEdxT variable - see debug streamer:
+  //
+  // Debug stream variables:  (Where tu cut ?)
+  // chain0->Draw("Cl.fQ/dedxQ.fElements[1]>>his(100,0,3)","fraction2<0.6&&dedge>3","",1000000);
+  //         mean 1  sigma 0.25
+  // chain0->Draw("Cl.fMax/dedxM.fElements[1]>>his(100,0,3)","fraction2<0.6&&dedge>3","",1000000)
+  //         mean 1  sigma 0.25
+  // chain0->Draw("Cl.fQ/dedxQ.fElements[2]>>his(100,0,3)","fraction2<0.7&&dedge>3","",1000000)
+  //         mean 1 sigma 0.29
+  // chain0->Draw("Cl.fMax/dedxM.fElements[2]>>his(100,0,3)","fraction2<0.7&&dedge>3","",1000000)
+  //         mean 1 sigma 0.27
+  // chain0->Draw("Cl.fQ/dedxQ.fElements[3]>>his(100,0,3)","fraction2<0.8&&dedge>3","",1000000)
+  //         mean 1 sigma 0.32
+  // 
+  // chain0->Draw("Cl.fQ/dedxQ.fElements[4]>>his(100,0,3)","fraction2<0.9&&dedge>3","",1000000)
+  //         mean 1 sigma 0.4
+
+  // Fraction choosen 0.7
 
    if (!cluster) {
       Error("AddCluster", "Cluster not valid.");
       return;
    }
 
-   if (dedge < 3.) return;
-   if (fraction2 > 0.7) return;
+   if (dedge < kedge) return;
+   if (fraction2 > kfraction) return;
 
    //Int_t padType = GetPadType(cluster->GetX());
    Double_t xx[7];
@@ -475,34 +666,40 @@ void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t momenta
    xx[5] = TMath::Abs(cluster->GetZ()) - TMath::Abs(meanPos[4]);
    xx[6] = xx[5] * xx[5];
 
+   //
+   // Update fitters
+   //
    Int_t segment = cluster->GetDetector() % 36;
-   Double_t q = fgkUseTotalCharge ? ((Double_t)(cluster->GetQ())) : ((Double_t)(cluster->GetMax()));  // note: no normalization to pad size!
-
-   // just for debugging
-   Int_t row = 0;
-   Int_t pad = 0;
-   GetRowPad(cluster->GetX(), cluster->GetY(), row, pad);
-   fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
-   
+   Double_t q = fgkUseTotalCharge ? 
+     ((Double_t)(cluster->GetQ()/GetQNorm(cluster,parY[1], parZ[1]))) : ((Double_t)(cluster->GetMax()/GetMaxNorm(cluster,parY[1], parZ[1])));  
+      
    // correct charge by normalising to mean charge per track
-   q /= dedxQ[2];
+   q /= dedxQ[kinorm];
 
    // just for debugging
-   fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
 
    Double_t sqrtQ = TMath::Sqrt(q);
    Double_t logQ = fgkM * TMath::Log(1 + q / fgkM);
-   fSimpleFitter->GetFitter(segment, padType)->AddPoint(xx, q);
-   fSqrtFitter->GetFitter(segment, padType)->AddPoint(xx, sqrtQ);
-   fLogFitter->GetFitter(segment, padType)->AddPoint(xx, logQ);
-   fSingleSectorFitter->GetFitter(0, padType)->AddPoint(xx, q);
+   TLinearFitter * fitter =0;
+   //
+   fitter = fSimpleFitter->GetFitter(segment, padType);
+   fitter->AddPoint(xx, q);
+   //
+   fitter = fSqrtFitter->GetFitter(segment, padType);
+   fitter->AddPoint(xx, sqrtQ);
+   //
+   fitter = fLogFitter->GetFitter(segment, padType);
+   fitter->AddPoint(xx, logQ);
+   //
+   fitter=fSingleSectorFitter->GetFitter(0, padType);
+   fitter->AddPoint(xx, q);
 
    // this will be gone for the a new ROOT version > v5-17-05
    if (padType == kShortPads)
       fNShortClusters[segment]++;
-   else if (padType == kMediumPads)
+   if (padType == kMediumPads)
       fNMediumClusters[segment]++;
-   else if (padType == kLongPads)
+   if (padType == kLongPads)
       fNLongClusters[segment]++;
 }
 
@@ -518,6 +715,19 @@ void AliTPCcalibTracksGain::Evaluate(Bool_t robust, Double_t frac) {
    fSqrtFitter->Evaluate(robust, frac);
    fLogFitter->Evaluate(robust, frac);
    fSingleSectorFitter->Evaluate(robust, frac);
+   fFitter0M->Eval();
+   fFitter1M->Eval();
+   fFitter2M->Eval();
+   fFitter0T->Eval();
+   fFitter1T->Eval();
+   fFitter2T->Eval();
+   //
+   fDFitter0M->Eval();
+   fDFitter1M->Eval();
+   fDFitter2M->Eval();
+   fDFitter0T->Eval();
+   fDFitter1T->Eval();
+   fDFitter2T->Eval();
 }
 
 AliTPCCalPad* AliTPCcalibTracksGain::CreateFitCalPad(UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
@@ -663,15 +873,24 @@ AliTPCCalROC* AliTPCcalibTracksGain::CreateCombinedCalROC(const AliTPCCalROC* ro
    return roc;
 }
 
-void AliTPCcalibTracksGain::GetParameters(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitParam) {
+Bool_t AliTPCcalibTracksGain::GetParameters(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitParam) {
    //
    // Puts the fit parameters for the specified segment (IROC & OROC), padType and fitType
    // into the fitParam TVectorD (which should contain 8 elements).
    // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
    // Note: The fitter has to be evaluated first!
    //
-
-   GetFitter(segment, padType, fitType)->GetParameters(fitParam);
+  TLinearFitter * fitter = GetFitter(segment, padType, fitType);
+  if (fitter){
+    fitter->Eval();
+    fitter->GetParameters(fitParam);
+    return kTRUE;
+  }else{
+    Error("AliTPCcalibTracksGain::GetParameters",
+         Form("Fitter%d_%d_%d not availble", segment, padType, fitType));
+    return kFALSE;
+  }
+  return kFALSE;
 }
 
 void AliTPCcalibTracksGain::GetErrors(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitError) {
@@ -772,93 +991,137 @@ Int_t AliTPCcalibTracksGain::GetPadType(Double_t lx) {
    return -1;
 }
 
-// ONLY FOR DEBUGGING PURPOSES - REMOVE ME WHEN NOT NEEDED ANYMORE
-Bool_t AliTPCcalibTracksGain::GetRowPad(Double_t lx, Double_t ly, Int_t& row, Int_t& pad) {
-   //
-   // Calculate the row and pad number when the local coordinates are given.
-   // Returns kFALSE if the position is out of range, otherwise return kTRUE.
-   // WARNING: This function is preliminary and probably isn't very accurate!!
-   //
-   
-   Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
-   //Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
-   Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
-   //Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
-   Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
-   //Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
-
-   if (GetPadType(lx) == 0) {
-      row = (Int_t)((lx - irocLow) / fgTPCparam->GetInnerPadPitchLength());
-      pad = (Int_t)((ly + fgTPCparam->GetYInner(row)) / fgTPCparam->GetInnerPadPitchWidth());
-   } else if (GetPadType(lx) == 1) {
-      row = (Int_t)((lx - orocLow1) / fgTPCparam->GetOuter1PadPitchLength());
-      pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
-   } else if (GetPadType(lx) == 2) {
-      row = fgTPCparam->GetNRowUp1() + (Int_t)((lx - orocLow2) / fgTPCparam->GetOuter2PadPitchLength());
-      pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
-   }
-   else return kFALSE;
-   return kTRUE;
-}
-
 void AliTPCcalibTracksGain::DumpTrack(AliTPCseed* track) {
    //
    //  Dump track information to the debug stream
    //
    
-   (*fDebugStream) << "Track" <<
-      "Track.=" << track <<        // track information
-      "\n";
    Int_t rows[200];
+   Int_t sector[3];
+   Int_t npoints[3];
+   TVectorD dedxM[3];
+   TVectorD dedxQ[3];
+   TVectorD parY[3];
+   TVectorD parZ[3];
+   TVectorD meanPos[3];
+   //
+   Int_t count=0;
    for (Int_t ipad = 0; ipad < 3; ipad++) {
-      GetDedx(track, ipad, rows);
+     dedxM[ipad].ResizeTo(5);
+     dedxQ[ipad].ResizeTo(5);
+     parY[ipad].ResizeTo(3);
+     parZ[ipad].ResizeTo(3);
+     meanPos[ipad].ResizeTo(6);
+     Bool_t isOK = GetDedx(track, ipad, rows, sector[ipad], npoints[ipad], dedxM[ipad], dedxQ[ipad], parY[ipad], parZ[ipad], meanPos[ipad]);
+     if (isOK) 
+       AddTracklet(sector[ipad],ipad, dedxQ[ipad], dedxM[ipad], parY[ipad], parZ[ipad], meanPos[ipad] );
+     if (isOK) count++;
    }
-}
 
-Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* rows) {
-   //
-   // GetDedx for given sector for given track
-   // padType - type of pads
-   //
-   
-   Int_t firstRow = 0, lastRow = 0;
-   Int_t minRow = 100;
-   Float_t xcenter = 0;
-   const Float_t ktany = TMath::Tan(TMath::DegToRad() * 10);
-   const Float_t kedgey = 4.;
-   if (padType == 0) {
-      firstRow = 0;
-      lastRow = fgTPCparam->GetNRowLow();
-      xcenter = 108.47;
-   }
-   if (padType == 1) {
-      firstRow = fgTPCparam->GetNRowLow();
-      lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
-      xcenter = 166.60;
+   TTreeSRedirector * cstream =  GetDebugStreamer();
+   if (cstream){
+     (*cstream) << "Track" <<
+       "run="<<fRun<<              //  run number
+       "event="<<fEvent<<          //  event number
+       "time="<<fTime<<            //  time stamp of event
+       "trigger="<<fTrigger<<      //  trigger
+       "mag="<<fMagF<<             //  magnetic field        
+       "Track.=" << track <<        // track information
+       "\n";
+     //
+     //
+     //
+     if ( GetStreamLevel()>1 && count>1){
+       (*cstream) << "TrackG" <<
+        "run="<<fRun<<              //  run number
+        "event="<<fEvent<<          //  event number
+        "time="<<fTime<<            //  time stamp of event
+        "trigger="<<fTrigger<<      //  trigger
+        "mag="<<fMagF<<             //  magnetic field       
+        "Track.=" << track <<        // track information
+        "ncount="<<count<<
+        // info for pad type 0
+        "sector0="<<sector[0]<<     
+        "npoints0="<<npoints[0]<<
+        "dedxM0.="<<&dedxM[0]<<
+        "dedxQ0.="<<&dedxQ[0]<<
+        "parY0.="<<&parY[0]<<
+        "parZ0.="<<&parZ[0]<<
+        "meanPos0.="<<&meanPos[0]<<
+        //
+        // info for pad type 1
+        "sector1="<<sector[1]<<     
+        "npoints1="<<npoints[1]<<
+        "dedxM1.="<<&dedxM[1]<<
+        "dedxQ1.="<<&dedxQ[1]<<
+        "parY1.="<<&parY[1]<<
+        "parZ1.="<<&parZ[1]<<
+        "meanPos1.="<<&meanPos[1]<<
+        //
+        // info for pad type 2
+        "sector2="<<sector[2]<<     
+        "npoints2="<<npoints[2]<<
+        "dedxM2.="<<&dedxM[2]<<
+        "dedxQ2.="<<&dedxQ[2]<<
+        "parY2.="<<&parY[2]<<
+        "parZ2.="<<&parZ[2]<<
+        "meanPos2.="<<&meanPos[2]<<
+        //       
+        "\n";
+     }
    }
-   if (padType == 2) {
-      firstRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
-      lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp();
-      xcenter = 222.6;
+}
+
+Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* /*rows*/,
+                                     Int_t &sector, Int_t& npoints, 
+                                     TVectorD &dedxM, TVectorD &dedxQ, 
+                                     TVectorD &parY, TVectorD &parZ, TVectorD&meanPos)
+{
+  //
+  // GetDedx for given sector for given track
+  // padType - type of pads
+  //
+
+  static TLinearFitter fitY(2, "pol1");
+  static TLinearFitter fitZ(2, "pol1");
+  fitY.StoreData(kFALSE);
+  fitZ.StoreData(kFALSE);
+  //
+  //   
+  Int_t firstRow = 0, lastRow = 0;
+  Int_t minRow = 100;
+  Float_t xcenter = 0;
+  const Float_t ktany = TMath::Tan(TMath::DegToRad() * 10);
+  const Float_t kedgey = 4.;
+  if (padType == 0) {
+    firstRow = 0;
+    lastRow = fgTPCparam->GetNRowLow();
+    xcenter = 108.47;
+  }
+  if (padType == 1) {
+    firstRow = fgTPCparam->GetNRowLow();
+    lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
+    xcenter = 166.60;
    }
-   minRow = (lastRow - firstRow) / 2;
-   //
-   //
-   Int_t nclusters = 0;
-   Int_t nclustersNE = 0; // number of not edge clusters
-   Int_t lastSector = -1;
-   Float_t amplitudeQ[100];
-   Float_t amplitudeM[100];
+  if (padType == 2) {
+    firstRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
+    lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp();
+    xcenter = 222.6;
+  }
+  minRow = (lastRow - firstRow) / 2;
+  //
+  //
+  Int_t nclusters = 0;
+  Int_t nclustersNE = 0; // number of not edge clusters
+  Int_t lastSector = -1;
+  Float_t amplitudeQ[100];
+  Float_t amplitudeM[100];
    Int_t rowIn[100];
    Int_t index[100];
    //
-   static TLinearFitter fitY(2, "pol1");
-   static TLinearFitter fitZ(2, "pol1");
-   static TVectorD parY(2);
-   static TVectorD parZ(2);
+   //
    fitY.ClearPoints();
    fitZ.ClearPoints();
-   TVectorD meanPos(6);
    
    for (Int_t iCluster = firstRow; iCluster < lastRow; iCluster++) {
       AliTPCclusterMI* cluster = track->GetClusterPointer(iCluster);
@@ -866,8 +1129,8 @@ Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* r
          Int_t detector = cluster->GetDetector() ;
          if (lastSector == -1) lastSector = detector;
          if (lastSector != detector) continue;
-         amplitudeQ[nclusters] = cluster->GetQ();
-         amplitudeM[nclusters] = cluster->GetMax();
+         amplitudeQ[nclusters] = cluster->GetQ()/GetQNorm(cluster,parY[1], parZ[1]);
+         amplitudeM[nclusters] = cluster->GetMax()/GetMaxNorm(cluster,parY[1], parZ[1]);
          rowIn[nclusters] = iCluster;
          nclusters++;
          Double_t dx = cluster->GetX() - xcenter;
@@ -896,9 +1159,9 @@ Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* r
    // calculate truncated mean
    //
    TMath::Sort(nclusters, amplitudeQ, index, kFALSE);
-   
-   TVectorD dedxQ(5);
-   TVectorD dedxM(5);
+   //
+   //
+   //
    Float_t ndedx[5];
    for (Int_t i = 0; i < 5; i++) {
       dedxQ[i] = 0;
@@ -945,8 +1208,10 @@ Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* r
       dedxQ[i] /= ndedx[i];
       dedxM[i] /= ndedx[i];
    }
-   
+   TTreeSRedirector * cstream =  GetDebugStreamer();   
    inonEdge = 0;
+   Float_t momenta = track->GetP();
+   Float_t mdedx = track->GetdEdx();
    for (Int_t i = 0; i < nclusters; i++) {
       Int_t rowSorted = rowIn[index[i]];
       AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
@@ -958,26 +1223,189 @@ Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* r
       Float_t dedge = cluster->GetX()*ktany - TMath::Abs(cluster->GetY());
       Float_t fraction = Float_t(i) / Float_t(nclusters);
       Float_t fraction2 = Float_t(inonEdge) / Float_t(nclustersNE);
-      Float_t momenta = track->GetP();
-      Float_t mdedx = track->GetdEdx();
 
       AddCluster(cluster, momenta, mdedx, padType, xcenter, dedxQ, dedxM, fraction, fraction2, dedge, parY, parZ, meanPos);
-
-      (*fDebugStream) << "dEdx" <<
-         "Cl.=" << cluster <<           // cluster of interest
-         "P=" << momenta <<             // track momenta
-         "dedx=" << mdedx <<            // mean dedx - corrected for angle
-         "IPad=" << padType <<          // pad type 0..2
-         "xc=" << xcenter <<            // x center of chamber
-         "dedxQ.=" << &dedxQ <<         // dedxQ  - total charge
-         "dedxM.=" << &dedxM <<         // dedxM  - maximal charge
-         "fraction=" << fraction <<     // fraction - order in statistic (0,1)
-         "fraction2=" << fraction2 <<   // fraction - order in statistic (0,1)
-         "dedge=" << dedge <<           // distance to the edge
-         "parY.=" << &parY <<           // line fit
-         "parZ.=" << &parZ <<           // line fit
-         "meanPos.=" << &meanPos <<     // mean position (dx, dx^2, y,y^2, z, z^2)
-         "\n";
+      
+      Double_t qNorm = GetQNorm(cluster,parY[1], parZ[1]);
+      Double_t mNorm = GetMaxNorm(cluster,parY[1], parZ[1]);
+
+
+      Float_t gain = GetGain(cluster);
+      if (cstream) (*cstream) << "dEdx" <<
+       "run="<<fRun<<              //  run number
+       "event="<<fEvent<<          //  event number
+       "time="<<fTime<<            //  time stamp of event
+       "trigger="<<fTrigger<<      //  trigger
+       "mag="<<fMagF<<             //  magnetic field        
+
+       "Cl.=" << cluster <<           // cluster of interest
+       "gain="<<gain<<                // gain at cluster position
+       "mNorm="<<mNorm<<              // Q max normalization
+       "qNorm="<<qNorm<<              // Q tot normalization
+       "P=" << momenta <<             // track momenta
+       "dedx=" << mdedx <<            // mean dedx - corrected for angle
+       "IPad=" << padType <<          // pad type 0..2
+       "xc=" << xcenter <<            // x center of chamber
+       "dedxQ.=" << &dedxQ <<         // dedxQ  - total charge
+       "dedxM.=" << &dedxM <<         // dedxM  - maximal charge
+       "fraction=" << fraction <<     // fraction - order in statistic (0,1)
+       "fraction2=" << fraction2 <<   // fraction - order in statistic (0,1)
+       "dedge=" << dedge <<           // distance to the edge
+       "parY.=" << &parY <<           // line fit
+       "parZ.=" << &parZ <<           // line fit
+       "meanPos.=" << &meanPos <<     // mean position (dx, dx^2, y,y^2, z, z^2)
+       "\n";
    }
+   
+   if (cstream) (*cstream) << "dEdxT" <<
+     "run="<<fRun<<              //  run number
+     "event="<<fEvent<<          //  event number
+     "time="<<fTime<<            //  time stamp of event
+     "trigger="<<fTrigger<<      //  trigger
+     "mag="<<fMagF<<             //  magnetic field          
+     "P=" << momenta <<             // track momenta
+     "npoints="<<inonEdge<<         // number of points
+     "sector="<<lastSector<<        // sector number
+     "dedx=" << mdedx <<            // mean dedx - corrected for angle
+     "IPad=" << padType <<          // pad type 0..2
+     "xc=" << xcenter <<            // x center of chamber
+     "dedxQ.=" << &dedxQ <<         // dedxQ  - total charge
+     "dedxM.=" << &dedxM <<         // dedxM  - maximal charge
+     "parY.=" << &parY <<           // line fit
+     "parZ.=" << &parZ <<           // line fit
+     "meanPos.=" << &meanPos <<     // mean position (dx, dx^2, y,y^2, z, z^2)
+     "\n";
+   
+   sector = lastSector;
+   npoints = inonEdge;
    return kTRUE;
 }
+
+void AliTPCcalibTracksGain::AddTracklet(UInt_t sector, UInt_t padType,TVectorD &dedxQ, TVectorD &dedxM,TVectorD& parY, TVectorD& parZ, TVectorD& meanPos){
+  //
+  // Add measured point - dedx to the fitter
+  //
+  //
+  //chain->SetAlias("dr","(250-abs(meanPos.fElements[4]))/250");
+  //chain->SetAlias("tz","(0+abs(parZ.fElements[1]))");
+  //chain->SetAlias("ty","(0+abs(parY.fElements[1]))");
+  //chain->SetAlias("corrg","sqrt((1+ty^2)*(1+tz^2))");
+  //expession fast - TString *strq0 = toolkit.FitPlane(chain,"dedxQ.fElements[2]","dr++ty++tz++dr*ty++dr*tz++ty*tz++ty^2++tz^2","IPad==0",chi2,npoints,param,covar,0,100000);
+
+  Double_t xxx[100];
+  //
+  // z and angular part
+  //
+  xxx[0] = (250.-TMath::Abs(meanPos[4]))/250.;
+  xxx[1] = TMath::Abs(parY[1]);
+  xxx[2] = TMath::Abs(parZ[1]);
+  xxx[3] = xxx[0]*xxx[1];
+  xxx[4] = xxx[0]*xxx[2];
+  xxx[5] = xxx[1]*xxx[2];
+  xxx[6] = xxx[0]*xxx[0];
+  xxx[7] = xxx[1]*xxx[1];
+  xxx[8] = xxx[2]*xxx[2];
+  //
+  // chamber part
+  //
+  Int_t tsector = sector%36;
+  for (Int_t i=0;i<35;i++){
+    xxx[9+i]=(i==tsector)?1:0;
+  }
+  TLinearFitter *fitterM = fFitter0M;
+  if (padType==1) fitterM=fFitter1M;
+  if (padType==2) fitterM=fFitter2M;
+  fitterM->AddPoint(xxx,dedxM[1]);
+  //
+  TLinearFitter *fitterT = fFitter0T;
+  if (padType==1) fitterT = fFitter1T;
+  if (padType==2) fitterT = fFitter2T;
+  fitterT->AddPoint(xxx,dedxQ[1]);
+  //
+  TLinearFitter *dfitterM = fDFitter0M;
+  if (padType==1) dfitterM=fDFitter1M;
+  if (padType==2) dfitterM=fDFitter2M;
+  dfitterM->AddPoint(xxx,dedxM[1]);
+  //
+  TLinearFitter *dfitterT = fDFitter0T;
+  if (padType==1) dfitterT = fDFitter1T;
+  if (padType==2) dfitterT = fDFitter2T;
+  dfitterT->AddPoint(xxx,dedxQ[1]);
+}
+
+
+TGraph *AliTPCcalibTracksGain::CreateAmpGraph(Int_t ipad, Bool_t qmax){
+  //
+  // create the amplitude graph
+  // The normalized amplitudes are extrapolated to the 0 angle (y,z)  and 0 drift length
+  //
+  
+  TVectorD vec;
+  if (qmax){
+    if (ipad==0) fFitter0M->GetParameters(vec);
+    if (ipad==1) fFitter1M->GetParameters(vec);
+    if (ipad==2) fFitter2M->GetParameters(vec);
+  }else{
+    if (ipad==0) fFitter0T->GetParameters(vec);
+    if (ipad==1) fFitter1T->GetParameters(vec);
+    if (ipad==2) fFitter2T->GetParameters(vec);
+  }
+  
+  Float_t amp[36];
+  Float_t sec[36];
+  for (Int_t i=0;i<35;i++){
+    sec[i]=i;
+    amp[i]=vec[10+i]+vec[0];
+  }
+  amp[35]=vec[0];
+  Float_t mean = TMath::Mean(36,amp);
+  for (Int_t i=0;i<36;i++){
+    sec[i]=i;
+    amp[i]=(amp[i]-mean)/mean;
+  }
+  TGraph *gr = new TGraph(36,sec,amp);
+  return gr;
+}
+
+
+void   AliTPCcalibTracksGain::UpdateClusterParam(AliTPCClusterParam* clparam){
+  //
+  //   SetQ normalization parameters
+  //
+  //  void SetQnorm(Int_t ipad, Int_t itype,  TVectorD * norm); 
+
+  TVectorD vec;
+  
+  //
+  fDFitter0T->Eval();
+  fDFitter1T->Eval();
+  fDFitter2T->Eval();
+  fDFitter0M->Eval();
+  fDFitter1M->Eval();
+  fDFitter2M->Eval();
+  fDFitter0T->GetParameters(vec);
+  clparam->SetQnorm(0,0,&vec);
+  fDFitter1T->GetParameters(vec);
+  clparam->SetQnorm(1,0,&vec);
+  fDFitter2T->GetParameters(vec);
+  clparam->SetQnorm(2,0,&vec);
+  //
+  fDFitter0M->GetParameters(vec);
+  clparam->SetQnorm(0,1,&vec);
+  fDFitter1M->GetParameters(vec);
+  clparam->SetQnorm(1,1,&vec);
+  fDFitter2M->GetParameters(vec);
+  clparam->SetQnorm(2,1,&vec);
+  //
+
+}
+
+
+void   AliTPCcalibTracksGain::Analyze(){
+
+ Evaluate();
+
+}
+
+