LCOV - code coverage report
Current view: top level - TPC/TPCbase - AliTPCClusterParam.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 124 1138 10.9 %
Date: 2016-06-14 17:26:59 Functions: 13 53 24.5 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : 
      17             : /// \class AliTPCClusterParam
      18             : /// \brief TPC cluster error, shape and charge parameterization as function of drift length and inclination angle
      19             : ///
      20             : /// Following notation is used in following
      21             : /// Int_t dim 0 - y direction
      22             : /// 1 - z direction
      23             : ///
      24             : /// Int_t type 0 - short pads
      25             : /// 1 - medium pads
      26             : /// 2 - long pads
      27             : /// Float_t z    - drift length
      28             : ///
      29             : /// Float_t angle - tangent of inclination angle at given dimension
      30             : ///
      31             : /// Implemented parameterization
      32             : ///
      33             : /// 1. Resolution as function of drift length and inclination angle
      34             : ///   1.a) GetError0(Int_t dim, Int_t type, Float_t z, Float_t angle)
      35             : /// Simple error parameterization as derived from analytical formula
      36             : /// only linear term in drift length and angle^2
      37             : /// The formula is valid only with precission +-5%
      38             : /// Separate parameterization for differnt pad geometry
      39             : ///   1.b) GetError0Par
      40             : /// Parabolic term correction - better precision
      41             : ///
      42             : ///   1.c) GetError1 - JUST FOR Study
      43             : /// Similar to GetError1
      44             : /// The angular and diffusion effect is scaling with pad length
      45             : /// common parameterization for different pad length
      46             : ///
      47             : /// 2. Error parameterization using charge
      48             : ///   2.a) GetErrorQ
      49             : /// GetError0+
      50             : /// adding 1/Q component to diffusion and angluar part
      51             : ///   2.b) GetErrorQPar
      52             : /// GetError0Par+
      53             : /// adding 1/Q component to diffusion and angluar part
      54             : ///   2.c) GetErrorQParScaled - Just for study
      55             : /// One parameterization for all pad shapes
      56             : /// Smaller precission as previous one
      57             : ///
      58             : /// Example how to retrieve the paramterization:
      59             : ///
      60             : /// ~~~{.cpp}
      61             : /// AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
      62             : /// AliCDBManager::Instance()->SetRun(0)
      63             : /// AliTPCClusterParam * param = AliTPCcalibDB::Instance()->GetClusterParam();
      64             : ///
      65             : /// AliTPCClusterParam::SetInstance(param);
      66             : /// TF1 f1("f1","AliTPCClusterParam::SGetError0Par(1,0,x,0)",0,250);
      67             : /// ~~~
      68             : ///
      69             : /// Example how to create parameterization:
      70             : /// Note resol is the resolution tree created by AliTPCcalibTracks
      71             : ///
      72             : /// ~~~{.cpp}
      73             : /// AliTPCClusterParam  *param = new AliTPCClusterParam;
      74             : /// param->FitData(Resol);
      75             : /// AliTPCClusterParam::SetInstance(param);
      76             : /// ~~~
      77             : 
      78             : #include "AliTPCClusterParam.h"
      79             : #include "TMath.h"
      80             : #include "TFile.h"
      81             : #include "TTree.h"
      82             : #include <TVectorF.h>
      83             : #include <TLinearFitter.h>
      84             : #include <TH1F.h>
      85             : #include <TH3F.h>
      86             : #include <TProfile2D.h>
      87             : #include <TVectorD.h>
      88             : #include <TObjArray.h>
      89             : #include "AliTPCcalibDB.h"
      90             : #include "AliTPCParam.h"
      91             : #include "THnBase.h"
      92             : #include <RVersion.h>
      93             : #if ROOT_VERSION_CODE < ROOT_VERSION(6,3,3)
      94             : #include "TFormulaPrimitive.h"
      95             : #else
      96             : #include "v5/TFormulaPrimitive.h"
      97             : #endif
      98             : #include "AliMathBase.h"
      99             : 
     100             : /// \cond CLASSIMP
     101          24 : ClassImp(AliTPCClusterParam)
     102             : /// \endcond
     103             : 
     104             : 
     105             : AliTPCClusterParam* AliTPCClusterParam::fgInstance = 0;
     106             : 
     107             : 
     108             : /*
     109             :   Example usage fitting parameterization:
     110             :   TFile fres("resol.root");    //tree with resolution and shape
     111             :   TTree * treeRes =(TTree*)fres.Get("Resol");
     112             : 
     113             :   AliTPCClusterParam param;
     114             :   param.SetInstance(&param);
     115             :   param.FitResol(treeRes);
     116             :   param.FitRMS(treeRes);
     117             :   TFile fparam("TPCClusterParam.root","recreate");
     118             :   param.Write("Param");
     119             :   //
     120             :   //
     121             :   TFile fparam("TPCClusterParam.root");
     122             :   AliTPCClusterParam *param2  =  (AliTPCClusterParam *) fparam.Get("Param");
     123             :   param2->SetInstance(param2);
     124             :   param2->Test(treeRes);
     125             : 
     126             : 
     127             :   treeRes->Draw("(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol","Dim==0&&QMean<0")
     128             : 
     129             : */
     130             : 
     131             : 
     132             : 
     133             : Double_t AliTPCClusterParamClusterResolutionY(Double_t x, Double_t s0, Double_t s1){
     134             :   //
     135             :   // cluster resoultion
     136           0 :   Double_t result = AliTPCClusterParam::SGetError0Par(0,s0,x,s1);
     137           0 :   return result;
     138             : }
     139             : 
     140             : Double_t AliTPCClusterParamClusterResolutionZ(Double_t x, Double_t s0, Double_t s1){
     141             :   //
     142             :   // cluster resoultion
     143           0 :   Double_t result = AliTPCClusterParam::SGetError0Par(1,s0,x,s1);
     144           0 :   return result;
     145             : }
     146             : 
     147             : 
     148             : 
     149             : //_ singleton implementation __________________________________________________
     150             : AliTPCClusterParam* AliTPCClusterParam::Instance()
     151             : {
     152             :   /// Singleton implementation
     153             :   /// Returns an instance of this class, it is created if neccessary
     154             : 
     155           0 :   if (fgInstance == 0){
     156           0 :     fgInstance = new AliTPCClusterParam();
     157             :     //
     158           0 :     ::Info("AliTPCClusterParam::Instance()","registering of the cluster param function primitives");
     159           0 :     ::Info("AliTPCClusterParam::Instance()","clusterResolutionYAliRoot");
     160             : #if ROOT_VERSION_CODE < ROOT_VERSION(6,3,3)
     161           0 :     TFormulaPrimitive::AddFormula(new TFormulaPrimitive("clusterResolutionYAliRoot","clusterResolutionYAliRoot",AliTPCClusterParamClusterResolutionY));
     162             : #else
     163             :     ROOT::v5::TFormulaPrimitive::AddFormula(new ROOT::v5::TFormulaPrimitive("clusterResolutionYAliRoot","clusterResolutionYAliRoot",AliTPCClusterParamClusterResolutionY));
     164             : #endif
     165           0 :     ::Info("AliTPCClusterParam::Instance()","clusterResolutionZAliRoot");
     166             : #if ROOT_VERSION_CODE < ROOT_VERSION(6,3,3)
     167           0 :     TFormulaPrimitive::AddFormula(new TFormulaPrimitive("clusterResolutionZAliRoot","clusterResolutionZAliRoot",AliTPCClusterParamClusterResolutionZ));
     168             : #else
     169             :     ROOT::v5::TFormulaPrimitive::AddFormula(new ROOT::v5::TFormulaPrimitive("clusterResolutionZAliRoot","clusterResolutionZAliRoot",AliTPCClusterParamClusterResolutionZ));
     170             : #endif
     171             : 
     172           0 :   }
     173           0 :   return fgInstance;
     174           0 : }
     175             : 
     176             : 
     177             : AliTPCClusterParam::AliTPCClusterParam():
     178           3 :   TObject(),
     179           3 :   fRatio(0),
     180           3 :   fQNorm(0),
     181           3 :   fQNormCorr(0),
     182           3 :   fQNormHis(0),
     183           3 :   fQpadTnorm(0),           // q pad normalization - Total charge
     184           3 :   fQpadMnorm(0),           // q pad normalization - Max charge
     185           3 :   fWaveCorrectionMap(0),
     186           3 :   fWaveCorrectionMirroredPad( kFALSE ),
     187           3 :   fWaveCorrectionMirroredZ( kFALSE ),
     188           3 :   fWaveCorrectionMirroredAngle( kFALSE ),
     189           3 :   fResolutionYMap(0)
     190             :   //
     191          15 : {
     192             :   /// Default constructor
     193             : 
     194           3 :   fPosQTnorm[0] = 0;   fPosQTnorm[1] = 0;   fPosQTnorm[2] = 0;
     195           3 :   fPosQMnorm[0] = 0;   fPosQMnorm[1] = 0;   fPosQMnorm[2] = 0;
     196             :   //
     197           3 :   fPosYcor[0]   = 0;   fPosYcor[1]   = 0;   fPosYcor[2]   = 0;
     198           3 :   fPosZcor[0]   = 0;   fPosZcor[1]   = 0;   fPosZcor[2]   = 0;
     199           3 :   fErrorRMSSys[0]=0;   fErrorRMSSys[1]=0;
     200           6 : }
     201             : 
     202             : AliTPCClusterParam::AliTPCClusterParam(const AliTPCClusterParam& param):
     203           0 :   TObject(param),
     204           0 :   fRatio(0),
     205           0 :   fQNorm(0),
     206           0 :   fQNormCorr(0),
     207           0 :   fQNormHis(0),
     208           0 :   fQpadTnorm(new TVectorD(*(param.fQpadTnorm))),           // q pad normalization - Total charge
     209           0 :   fQpadMnorm(new TVectorD(*(param.fQpadMnorm))),           // q pad normalization - Max charge
     210           0 :   fWaveCorrectionMap(0),
     211           0 :   fWaveCorrectionMirroredPad( kFALSE ),
     212           0 :   fWaveCorrectionMirroredZ( kFALSE ),
     213           0 :   fWaveCorrectionMirroredAngle( kFALSE ),
     214           0 :   fResolutionYMap(0)
     215           0 : {
     216             :   /// copy constructor
     217             : 
     218           0 :   if (param.fQNorm) fQNorm = (TObjArray*) param.fQNorm->Clone();
     219           0 :   if (param.fQNormHis) fQNormHis = (TObjArray*) param.fQNormHis->Clone();
     220             :   //
     221           0 :   if (param.fPosQTnorm[0]){
     222           0 :     fPosQTnorm[0] = new TVectorD(*(param.fPosQTnorm[0]));
     223           0 :     fPosQTnorm[1] = new TVectorD(*(param.fPosQTnorm[1]));
     224           0 :     fPosQTnorm[2] = new TVectorD(*(param.fPosQTnorm[2]));
     225             :     //
     226           0 :     fPosQMnorm[0] = new TVectorD(*(param.fPosQMnorm[0]));
     227           0 :     fPosQMnorm[1] = new TVectorD(*(param.fPosQMnorm[1]));
     228           0 :     fPosQMnorm[2] = new TVectorD(*(param.fPosQMnorm[2]));
     229           0 :   }
     230           0 :   if (param.fPosYcor[0]){
     231           0 :     fPosYcor[0] = new TVectorD(*(param.fPosYcor[0]));
     232           0 :     fPosYcor[1] = new TVectorD(*(param.fPosYcor[1]));
     233           0 :     fPosYcor[2] = new TVectorD(*(param.fPosYcor[2]));
     234             :     //
     235           0 :     fPosZcor[0] = new TVectorD(*(param.fPosZcor[0]));
     236           0 :     fPosZcor[1] = new TVectorD(*(param.fPosZcor[1]));
     237           0 :     fPosZcor[2] = new TVectorD(*(param.fPosZcor[2]));
     238           0 :   }
     239             : 
     240           0 :   for (Int_t ii = 0; ii < 2; ++ii) {
     241           0 :     for (Int_t jj = 0; jj < 3; ++jj) {
     242           0 :       for (Int_t kk = 0; kk < 4; ++kk) {
     243           0 :         fParamS0[ii][jj][kk] = param.fParamS0[ii][jj][kk];
     244           0 :         fErrorS0[ii][jj][kk] = param.fErrorS0[ii][jj][kk];
     245           0 :         fParamRMS0[ii][jj][kk] = param.fParamRMS0[ii][jj][kk];
     246           0 :         fErrorRMS0[ii][jj][kk] = param.fErrorRMS0[ii][jj][kk];
     247             :       }
     248           0 :       for (Int_t kk = 0; kk < 7; ++kk) {
     249           0 :         fParamS0Par[ii][jj][kk] = param.fParamS0Par[ii][jj][kk];
     250           0 :         fErrorS0Par[ii][jj][kk] = param.fErrorS0Par[ii][jj][kk];
     251             :       }
     252           0 :       for (Int_t kk = 0; kk < 6; ++kk) {
     253           0 :         fParamSQ[ii][jj][kk] = param.fParamSQ[ii][jj][kk];
     254           0 :         fErrorSQ[ii][jj][kk] = param.fErrorSQ[ii][jj][kk];
     255           0 :         fParamRMSQ[ii][jj][kk] = param.fParamRMSQ[ii][jj][kk];
     256           0 :         fErrorRMSQ[ii][jj][kk] = param.fErrorRMSQ[ii][jj][kk];
     257             :       }
     258           0 :       for (Int_t kk = 0; kk < 9; ++kk) {
     259           0 :         fParamSQPar[ii][jj][kk] = param.fParamSQPar[ii][jj][kk];
     260           0 :         fErrorSQPar[ii][jj][kk] = param.fErrorSQPar[ii][jj][kk];
     261             :       }
     262           0 :       for (Int_t kk = 0; kk < 2; ++kk) {
     263           0 :         fRMSSigmaFit[ii][jj][kk] = param.fRMSSigmaFit[ii][jj][kk];
     264             :       }
     265             :     }
     266           0 :     for (Int_t jj = 0; jj < 4; ++jj) {
     267           0 :       fParamS1[ii][jj] = param.fParamS1[ii][jj];
     268           0 :       fErrorS1[ii][jj] = param.fErrorS1[ii][jj];
     269             :     }
     270           0 :     for (Int_t jj = 0; jj < 5; ++jj) {
     271           0 :       fParamRMS1[ii][jj] = param.fParamRMS1[ii][jj];
     272           0 :       fErrorRMS1[ii][jj] = param.fErrorRMS1[ii][jj];
     273             :     }
     274           0 :     fErrorRMSSys[ii] = param.fErrorRMSSys[ii];
     275           0 :     for (Int_t jj = 0; jj < 2; ++jj){
     276           0 :       fRMSSigmaRatio[ii][jj] = param.fRMSSigmaRatio[ii][jj];
     277             :     }
     278             :   }
     279             : 
     280           0 :   SetWaveCorrectionMap( param.fWaveCorrectionMap );
     281           0 :   SetResolutionYMap( param.fResolutionYMap );
     282           0 : }
     283             : 
     284             : 
     285             : AliTPCClusterParam & AliTPCClusterParam::operator=(const AliTPCClusterParam& param){
     286             :   /// Assignment operator
     287             : 
     288           0 :   if (this != &param) {
     289           0 :     if (param.fQNorm) fQNorm = (TObjArray*) param.fQNorm->Clone();
     290           0 :     if (param.fQNormHis) fQNormHis = (TObjArray*) param.fQNormHis->Clone();
     291           0 :     if (param.fPosQTnorm[0]){
     292           0 :       fPosQTnorm[0] = new TVectorD(*(param.fPosQTnorm[0]));
     293           0 :       fPosQTnorm[1] = new TVectorD(*(param.fPosQTnorm[1]));
     294           0 :       fPosQTnorm[2] = new TVectorD(*(param.fPosQTnorm[2]));
     295             :       //
     296           0 :       fPosQMnorm[0] = new TVectorD(*(param.fPosQMnorm[0]));
     297           0 :       fPosQMnorm[1] = new TVectorD(*(param.fPosQMnorm[1]));
     298           0 :       fPosQMnorm[2] = new TVectorD(*(param.fPosQMnorm[2]));
     299           0 :     }
     300           0 :     if (param.fPosYcor[0]){
     301           0 :       fPosYcor[0] = new TVectorD(*(param.fPosYcor[0]));
     302           0 :       fPosYcor[1] = new TVectorD(*(param.fPosYcor[1]));
     303           0 :       fPosYcor[2] = new TVectorD(*(param.fPosYcor[2]));
     304             :       //
     305           0 :       fPosZcor[0] = new TVectorD(*(param.fPosZcor[0]));
     306           0 :       fPosZcor[1] = new TVectorD(*(param.fPosZcor[1]));
     307           0 :       fPosZcor[2] = new TVectorD(*(param.fPosZcor[2]));
     308           0 :     }
     309             : 
     310           0 :     for (Int_t ii = 0; ii < 2; ++ii) {
     311           0 :       for (Int_t jj = 0; jj < 3; ++jj) {
     312           0 :         for (Int_t kk = 0; kk < 4; ++kk) {
     313           0 :           fParamS0[ii][jj][kk] = param.fParamS0[ii][jj][kk];
     314           0 :           fErrorS0[ii][jj][kk] = param.fErrorS0[ii][jj][kk];
     315           0 :           fParamRMS0[ii][jj][kk] = param.fParamRMS0[ii][jj][kk];
     316           0 :           fErrorRMS0[ii][jj][kk] = param.fErrorRMS0[ii][jj][kk];
     317             :         }
     318           0 :         for (Int_t kk = 0; kk < 7; ++kk) {
     319           0 :           fParamS0Par[ii][jj][kk] = param.fParamS0Par[ii][jj][kk];
     320           0 :           fErrorS0Par[ii][jj][kk] = param.fErrorS0Par[ii][jj][kk];
     321             :         }
     322           0 :         for (Int_t kk = 0; kk < 6; ++kk) {
     323           0 :           fParamSQ[ii][jj][kk] = param.fParamSQ[ii][jj][kk];
     324           0 :           fErrorSQ[ii][jj][kk] = param.fErrorSQ[ii][jj][kk];
     325           0 :           fParamRMSQ[ii][jj][kk] = param.fParamRMSQ[ii][jj][kk];
     326           0 :           fErrorRMSQ[ii][jj][kk] = param.fErrorRMSQ[ii][jj][kk];
     327             :         }
     328           0 :         for (Int_t kk = 0; kk < 9; ++kk) {
     329           0 :           fParamSQPar[ii][jj][kk] = param.fParamSQPar[ii][jj][kk];
     330           0 :           fErrorSQPar[ii][jj][kk] = param.fErrorSQPar[ii][jj][kk];
     331             :         }
     332           0 :         for (Int_t kk = 0; kk < 2; ++kk) {
     333           0 :           fRMSSigmaFit[ii][jj][kk] = param.fRMSSigmaFit[ii][jj][kk];
     334             :         }
     335             :       }
     336           0 :       for (Int_t jj = 0; jj < 4; ++jj) {
     337           0 :         fParamS1[ii][jj] = param.fParamS1[ii][jj];
     338           0 :         fErrorS1[ii][jj] = param.fErrorS1[ii][jj];
     339             :       }
     340           0 :       for (Int_t jj = 0; jj < 5; ++jj) {
     341           0 :         fParamRMS1[ii][jj] = param.fParamRMS1[ii][jj];
     342           0 :         fErrorRMS1[ii][jj] = param.fErrorRMS1[ii][jj];
     343             :       }
     344           0 :       fErrorRMSSys[ii] = param.fErrorRMSSys[ii];
     345           0 :       for (Int_t jj = 0; jj < 2; ++jj){
     346           0 :         fRMSSigmaRatio[ii][jj] = param.fRMSSigmaRatio[ii][jj];
     347             :       }
     348             :     }
     349             : 
     350           0 :     SetWaveCorrectionMap( param.fWaveCorrectionMap );
     351           0 :     SetResolutionYMap( param.fResolutionYMap );
     352           0 :   }
     353           0 :   return *this;
     354           0 : }
     355             : 
     356             : 
     357          18 : AliTPCClusterParam::~AliTPCClusterParam(){
     358             :   /// destructor
     359             : 
     360           6 :   if (fQNorm) fQNorm->Delete();
     361           9 :   if (fQNormCorr) delete fQNormCorr;
     362           6 :   if (fQNormHis) fQNormHis->Delete();
     363           6 :   delete fQNorm;
     364           6 :   delete fQNormHis;
     365           3 :   if (fPosQTnorm[0]){
     366           6 :     delete fPosQTnorm[0];
     367           6 :     delete fPosQTnorm[1];
     368           6 :     delete fPosQTnorm[2];
     369             :     //
     370           6 :     delete fPosQMnorm[0];
     371           6 :     delete fPosQMnorm[1];
     372           6 :     delete fPosQMnorm[2];
     373             :   }
     374           3 :   if (fPosYcor[0]){
     375           6 :     delete fPosYcor[0];
     376           6 :     delete fPosYcor[1];
     377           6 :     delete fPosYcor[2];
     378             :     //
     379           6 :     delete fPosZcor[0];
     380           6 :     delete fPosZcor[1];
     381           6 :     delete fPosZcor[2];
     382             :   }
     383           3 :   delete fWaveCorrectionMap;
     384           3 :   delete fResolutionYMap;
     385           9 : }
     386             : 
     387             : 
     388             : void AliTPCClusterParam::FitResol0(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     389             :   /// Fit z - angular dependence of resolution
     390             :   ///
     391             :   /// Int_t dim=0, type=0;
     392             : 
     393           0 :   TString varVal;
     394           0 :   varVal="Resol:AngleM:Zm";
     395           0 :   TString varErr;
     396           0 :   varErr="Sigma:AngleS:Zs";
     397           0 :   TString varCut;
     398           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type);
     399             :   //
     400           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     401           0 :   Float_t px[10000], py[10000], pz[10000];
     402           0 :   Float_t ex[10000], ey[10000], ez[10000];
     403             :   //
     404           0 :   tree->Draw(varErr.Data(),varCut);
     405           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     406           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     407           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     408           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     409             :   }
     410           0 :   tree->Draw(varVal.Data(),varCut);
     411           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     412           0 :     px[ipoint]= tree->GetV3()[ipoint];
     413           0 :     py[ipoint]= tree->GetV2()[ipoint];
     414           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     415             :   }
     416             : 
     417             :   //
     418           0 :   TLinearFitter fitter(3,"hyp2");
     419           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     420           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     421           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     422           0 :     Double_t x[2];
     423           0 :     x[0] = px[ipoint];
     424           0 :     x[1] = py[ipoint]*py[ipoint];
     425           0 :     fitter.AddPoint(x,val,err);
     426           0 :   }
     427           0 :   fitter.Eval();
     428           0 :   TVectorD param(3);
     429           0 :   fitter.GetParameters(param);
     430           0 :   param0[0] = param[0];
     431           0 :   param0[1] = param[1];
     432           0 :   param0[2] = param[2];
     433           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     434           0 :   param0[3] = chi2;
     435           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     436           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     437           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     438           0 : }
     439             : 
     440             : 
     441             : void AliTPCClusterParam::FitResol0Par(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     442             :   /// Fit z - angular dependence of resolution
     443             :   ///
     444             :   /// Int_t dim=0, type=0;
     445             : 
     446           0 :  TString varVal;
     447           0 :   varVal="Resol:AngleM:Zm";
     448           0 :  TString varErr;
     449           0 :   varErr="Sigma:AngleS:Zs";
     450           0 :  TString varCut;
     451           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type);
     452             :   //
     453           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     454           0 :   Float_t px[10000], py[10000], pz[10000];
     455           0 :   Float_t ex[10000], ey[10000], ez[10000];
     456             :   //
     457           0 :   tree->Draw(varErr.Data(),varCut);
     458           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     459           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     460           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     461           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     462             :   }
     463           0 :   tree->Draw(varVal.Data(),varCut);
     464           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     465           0 :     px[ipoint]= tree->GetV3()[ipoint];
     466           0 :     py[ipoint]= tree->GetV2()[ipoint];
     467           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     468             :   }
     469             : 
     470             :   //
     471           0 :   TLinearFitter fitter(6,"hyp5");
     472           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     473           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     474           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     475           0 :     Double_t x[6];
     476           0 :     x[0] = px[ipoint];
     477           0 :     x[1] = py[ipoint]*py[ipoint];
     478           0 :     x[2] = x[0]*x[0];
     479           0 :     x[3] = x[1]*x[1];
     480           0 :     x[4] = x[0]*x[1];
     481           0 :     fitter.AddPoint(x,val,err);
     482           0 :   }
     483           0 :   fitter.Eval();
     484           0 :   TVectorD param(6);
     485           0 :   fitter.GetParameters(param);
     486           0 :   param0[0] = param[0];
     487           0 :   param0[1] = param[1];
     488           0 :   param0[2] = param[2];
     489           0 :   param0[3] = param[3];
     490           0 :   param0[4] = param[4];
     491           0 :   param0[5] = param[5];
     492           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     493           0 :   param0[6] = chi2;
     494           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     495           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     496           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     497           0 :   error[3] = (fitter.GetParError(3)*TMath::Sqrt(chi2));
     498           0 :   error[4] = (fitter.GetParError(4)*TMath::Sqrt(chi2));
     499           0 :   error[5] = (fitter.GetParError(5)*TMath::Sqrt(chi2));
     500           0 : }
     501             : 
     502             : 
     503             : 
     504             : 
     505             : 
     506             : void AliTPCClusterParam::FitResol1(TTree * tree, Int_t dim, Float_t *param0, Float_t *error){
     507             :   /// Fit z - angular dependence of resolution - pad length scaling
     508             :   ///
     509             :   /// Int_t dim=0, type=0;
     510             : 
     511           0 :  TString varVal;
     512           0 :   varVal="Resol:AngleM*sqrt(Length):Zm/Length";
     513           0 :  TString varErr;
     514           0 :   varErr="Sigma:AngleS:Zs";
     515           0 :  TString varCut;
     516           0 :   varCut=Form("Dim==%d&&QMean<0",dim);
     517             :   //
     518           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     519           0 :   Float_t px[10000], py[10000], pz[10000];
     520           0 :   Float_t ex[10000], ey[10000], ez[10000];
     521             :   //
     522           0 :   tree->Draw(varErr.Data(),varCut);
     523           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     524           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     525           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     526           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     527             :   }
     528           0 :   tree->Draw(varVal.Data(),varCut);
     529           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     530           0 :     px[ipoint]= tree->GetV3()[ipoint];
     531           0 :     py[ipoint]= tree->GetV2()[ipoint];
     532           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     533             :   }
     534             : 
     535             :   //
     536           0 :   TLinearFitter fitter(3,"hyp2");
     537           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     538           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     539           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     540           0 :     Double_t x[2];
     541           0 :     x[0] = px[ipoint];
     542           0 :     x[1] = py[ipoint]*py[ipoint];
     543           0 :     fitter.AddPoint(x,val,err);
     544           0 :   }
     545           0 :   fitter.Eval();
     546           0 :   TVectorD param(3);
     547           0 :   fitter.GetParameters(param);
     548           0 :   param0[0] = param[0];
     549           0 :   param0[1] = param[1];
     550           0 :   param0[2] = param[2];
     551           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     552           0 :   param0[3] = chi2;
     553           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     554           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     555           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     556           0 : }
     557             : 
     558             : void AliTPCClusterParam::FitResolQ(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     559             :   /// Fit z - angular dependence of resolution - Q scaling
     560             :   ///
     561             :   /// Int_t dim=0, type=0;
     562             : 
     563           0 :  TString varVal;
     564           0 :   varVal="Resol:AngleM/sqrt(QMean):Zm/QMean";
     565           0 :   char varVal0[100];
     566           0 :   snprintf(varVal0,100,"Resol:AngleM:Zm");
     567             :   //
     568           0 :  TString varErr;
     569           0 :   varErr="Sigma:AngleS:Zs";
     570           0 :  TString varCut;
     571           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type);
     572             :   //
     573           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     574           0 :   Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000];
     575           0 :   Float_t ex[20000], ey[20000], ez[20000];
     576             :   //
     577           0 :   tree->Draw(varErr.Data(),varCut);
     578           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     579           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     580           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     581           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     582             :   }
     583           0 :   tree->Draw(varVal.Data(),varCut);
     584           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     585           0 :     px[ipoint]= tree->GetV3()[ipoint];
     586           0 :     py[ipoint]= tree->GetV2()[ipoint];
     587           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     588             :   }
     589           0 :   tree->Draw(varVal0,varCut);
     590           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     591           0 :     pu[ipoint]= tree->GetV3()[ipoint];
     592           0 :     pt[ipoint]= tree->GetV2()[ipoint];
     593             :   }
     594             : 
     595             :   //
     596           0 :   TLinearFitter fitter(5,"hyp4");
     597           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     598           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     599           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     600           0 :     Double_t x[4];
     601           0 :     x[0] = pu[ipoint];
     602           0 :     x[1] = pt[ipoint]*pt[ipoint];
     603           0 :     x[2] = px[ipoint];
     604           0 :     x[3] = py[ipoint]*py[ipoint];
     605           0 :     fitter.AddPoint(x,val,err);
     606           0 :   }
     607             : 
     608           0 :   fitter.Eval();
     609           0 :   TVectorD param(5);
     610           0 :   fitter.GetParameters(param);
     611           0 :   param0[0] = param[0];
     612           0 :   param0[1] = param[1];
     613           0 :   param0[2] = param[2];
     614           0 :   param0[3] = param[3];
     615           0 :   param0[4] = param[4];
     616           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     617           0 :   param0[5] = chi2;
     618           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     619           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     620           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     621           0 :   error[3] = (fitter.GetParError(3)*TMath::Sqrt(chi2));
     622           0 :   error[4] = (fitter.GetParError(4)*TMath::Sqrt(chi2));
     623           0 : }
     624             : 
     625             : void AliTPCClusterParam::FitResolQPar(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     626             :   /// Fit z - angular dependence of resolution - Q scaling  - parabolic correction
     627             :   ///
     628             :   /// Int_t dim=0, type=0;
     629             : 
     630           0 :  TString varVal;
     631           0 :   varVal="Resol:AngleM/sqrt(QMean):Zm/QMean";
     632           0 :   char varVal0[100];
     633           0 :   snprintf(varVal0,100,"Resol:AngleM:Zm");
     634             :   //
     635           0 :  TString varErr;
     636           0 :   varErr="Sigma:AngleS:Zs";
     637           0 :  TString varCut;
     638           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type);
     639             :   //
     640           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     641           0 :   Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000];
     642           0 :   Float_t ex[20000], ey[20000], ez[20000];
     643             :   //
     644           0 :   tree->Draw(varErr.Data(),varCut);
     645           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     646           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     647           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     648           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     649             :   }
     650           0 :   tree->Draw(varVal.Data(),varCut);
     651           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     652           0 :     px[ipoint]= tree->GetV3()[ipoint];
     653           0 :     py[ipoint]= tree->GetV2()[ipoint];
     654           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     655             :   }
     656           0 :   tree->Draw(varVal0,varCut);
     657           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     658           0 :     pu[ipoint]= tree->GetV3()[ipoint];
     659           0 :     pt[ipoint]= tree->GetV2()[ipoint];
     660             :   }
     661             : 
     662             :   //
     663           0 :   TLinearFitter fitter(8,"hyp7");
     664           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     665           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     666           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     667           0 :     Double_t x[7];
     668           0 :     x[0] = pu[ipoint];
     669           0 :     x[1] = pt[ipoint]*pt[ipoint];
     670           0 :     x[2] = x[0]*x[0];
     671           0 :     x[3] = x[1]*x[1];
     672           0 :     x[4] = x[0]*x[1];
     673           0 :     x[5] = px[ipoint];
     674           0 :     x[6] = py[ipoint]*py[ipoint];
     675             :     //
     676           0 :     fitter.AddPoint(x,val,err);
     677           0 :   }
     678             : 
     679           0 :   fitter.Eval();
     680           0 :   TVectorD param(8);
     681           0 :   fitter.GetParameters(param);
     682           0 :   param0[0] = param[0];
     683           0 :   param0[1] = param[1];
     684           0 :   param0[2] = param[2];
     685           0 :   param0[3] = param[3];
     686           0 :   param0[4] = param[4];
     687           0 :   param0[5] = param[5];
     688           0 :   param0[6] = param[6];
     689           0 :   param0[7] = param[7];
     690             : 
     691           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     692           0 :   param0[8] = chi2;
     693           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     694           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     695           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     696           0 :   error[3] = (fitter.GetParError(3)*TMath::Sqrt(chi2));
     697           0 :   error[4] = (fitter.GetParError(4)*TMath::Sqrt(chi2));
     698           0 :   error[5] = (fitter.GetParError(5)*TMath::Sqrt(chi2));
     699           0 :   error[6] = (fitter.GetParError(6)*TMath::Sqrt(chi2));
     700           0 :   error[7] = (fitter.GetParError(7)*TMath::Sqrt(chi2));
     701           0 : }
     702             : 
     703             : 
     704             : 
     705             : void AliTPCClusterParam::FitRMS0(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     706             :   /// Fit z - angular dependence of resolution
     707             :   ///
     708             :   /// Int_t dim=0, type=0;
     709             : 
     710           0 :  TString varVal;
     711           0 :   varVal="RMSm:AngleM:Zm";
     712           0 :  TString varErr;
     713           0 :   varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs";
     714           0 :  TString varCut;
     715           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type);
     716             :   //
     717           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     718           0 :   Float_t px[10000], py[10000], pz[10000];
     719           0 :   Float_t ex[10000], ey[10000], ez[10000];
     720             :   //
     721           0 :   tree->Draw(varErr.Data(),varCut);
     722           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     723           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     724           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     725           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     726             :   }
     727           0 :   tree->Draw(varVal.Data(),varCut);
     728           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     729           0 :     px[ipoint]= tree->GetV3()[ipoint];
     730           0 :     py[ipoint]= tree->GetV2()[ipoint];
     731           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     732             :   }
     733             : 
     734             :   //
     735           0 :   TLinearFitter fitter(3,"hyp2");
     736           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     737           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     738           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     739           0 :     Double_t x[2];
     740           0 :     x[0] = px[ipoint];
     741           0 :     x[1] = py[ipoint]*py[ipoint];
     742           0 :     fitter.AddPoint(x,val,err);
     743           0 :   }
     744           0 :   fitter.Eval();
     745           0 :   TVectorD param(3);
     746           0 :   fitter.GetParameters(param);
     747           0 :   param0[0] = param[0];
     748           0 :   param0[1] = param[1];
     749           0 :   param0[2] = param[2];
     750           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     751           0 :   param0[3] = chi2;
     752           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     753           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     754           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     755           0 : }
     756             : 
     757             : void AliTPCClusterParam::FitRMS1(TTree * tree, Int_t dim, Float_t *param0, Float_t *error){
     758             :   /// Fit z - angular dependence of resolution - pad length scaling
     759             :   ///
     760             :   /// Int_t dim=0, type=0;
     761             : 
     762           0 :  TString varVal;
     763           0 :   varVal="RMSm:AngleM*Length:Zm";
     764           0 :  TString varErr;
     765           0 :   varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Pad";
     766           0 :  TString varCut;
     767           0 :   varCut=Form("Dim==%d&&QMean<0",dim);
     768             :   //
     769           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     770           0 :   Float_t px[10000], py[10000], pz[10000];
     771           0 :   Float_t type[10000], ey[10000], ez[10000];
     772             :   //
     773           0 :   tree->Draw(varErr.Data(),varCut);
     774           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     775           0 :     type[ipoint] = tree->GetV3()[ipoint];
     776           0 :     ey[ipoint]   = tree->GetV2()[ipoint];
     777           0 :     ez[ipoint]   = tree->GetV1()[ipoint];
     778             :   }
     779           0 :   tree->Draw(varVal.Data(),varCut);
     780           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     781           0 :     px[ipoint]= tree->GetV3()[ipoint];
     782           0 :     py[ipoint]= tree->GetV2()[ipoint];
     783           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     784             :   }
     785             : 
     786             :   //
     787           0 :   TLinearFitter fitter(4,"hyp3");
     788           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     789           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     790           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     791           0 :     Double_t x[3];
     792           0 :     x[0] = (type[ipoint]<0.5)? 0.:1.;
     793           0 :     x[1] = px[ipoint];
     794           0 :     x[2] = py[ipoint]*py[ipoint];
     795           0 :     fitter.AddPoint(x,val,err);
     796           0 :   }
     797           0 :   fitter.Eval();
     798           0 :   TVectorD param(4);
     799           0 :   fitter.GetParameters(param);
     800           0 :   param0[0] = param[0];
     801           0 :   param0[1] = param[0]+param[1];
     802           0 :   param0[2] = param[2];
     803           0 :   param0[3] = param[3];
     804           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     805           0 :   param0[4] = chi2;
     806           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     807           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     808           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     809           0 :   error[3] = (fitter.GetParError(3)*TMath::Sqrt(chi2));
     810           0 : }
     811             : 
     812             : void AliTPCClusterParam::FitRMSQ(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t *error){
     813             :   /// Fit z - angular dependence of resolution - Q scaling
     814             :   ///
     815             :   /// Int_t dim=0, type=0;
     816             : 
     817           0 :  TString varVal;
     818           0 :   varVal="RMSm:AngleM/sqrt(QMean):Zm/QMean";
     819           0 :   char varVal0[100];
     820           0 :   snprintf(varVal0,100,"RMSm:AngleM:Zm");
     821             :   //
     822           0 :  TString varErr;
     823           0 :   varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs";
     824           0 :  TString varCut;
     825           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type);
     826             :   //
     827           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     828           0 :   Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000];
     829           0 :   Float_t ex[20000], ey[20000], ez[20000];
     830             :   //
     831           0 :   tree->Draw(varErr.Data(),varCut);
     832           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     833           0 :     ex[ipoint]= tree->GetV3()[ipoint];
     834           0 :     ey[ipoint]= tree->GetV2()[ipoint];
     835           0 :     ez[ipoint]= tree->GetV1()[ipoint];
     836             :   }
     837           0 :   tree->Draw(varVal.Data(),varCut);
     838           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     839           0 :     px[ipoint]= tree->GetV3()[ipoint];
     840           0 :     py[ipoint]= tree->GetV2()[ipoint];
     841           0 :     pz[ipoint]= tree->GetV1()[ipoint];
     842             :   }
     843           0 :   tree->Draw(varVal0,varCut);
     844           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     845           0 :     pu[ipoint]= tree->GetV3()[ipoint];
     846           0 :     pt[ipoint]= tree->GetV2()[ipoint];
     847             :   }
     848             : 
     849             :   //
     850           0 :   TLinearFitter fitter(5,"hyp4");
     851           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     852           0 :     Float_t val = pz[ipoint]*pz[ipoint];
     853           0 :     Float_t err = 2*pz[ipoint]*TMath::Sqrt(ez[ipoint]*ez[ipoint]+fRatio*fRatio*pz[ipoint]*pz[ipoint]);
     854           0 :     Double_t x[4];
     855           0 :     x[0] = pu[ipoint];
     856           0 :     x[1] = pt[ipoint]*pt[ipoint];
     857           0 :     x[2] = px[ipoint];
     858           0 :     x[3] = py[ipoint]*py[ipoint];
     859           0 :     fitter.AddPoint(x,val,err);
     860           0 :   }
     861             : 
     862           0 :   fitter.Eval();
     863           0 :   TVectorD param(5);
     864           0 :   fitter.GetParameters(param);
     865           0 :   param0[0] = param[0];
     866           0 :   param0[1] = param[1];
     867           0 :   param0[2] = param[2];
     868           0 :   param0[3] = param[3];
     869           0 :   param0[4] = param[4];
     870           0 :   Float_t chi2 =  fitter.GetChisquare()/entries;
     871           0 :   param0[5] = chi2;
     872           0 :   error[0] = (fitter.GetParError(0)*TMath::Sqrt(chi2));
     873           0 :   error[1] = (fitter.GetParError(1)*TMath::Sqrt(chi2));
     874           0 :   error[2] = (fitter.GetParError(2)*TMath::Sqrt(chi2));
     875           0 :   error[3] = (fitter.GetParError(3)*TMath::Sqrt(chi2));
     876           0 :   error[4] = (fitter.GetParError(4)*TMath::Sqrt(chi2));
     877           0 : }
     878             : 
     879             : 
     880             : void AliTPCClusterParam::FitRMSSigma(TTree * tree, Int_t dim, Int_t type, Float_t *param0, Float_t */*error*/){
     881             :   /// Fit z - angular dependence of resolution - Q scaling
     882             :   ///
     883             :   /// Int_t dim=0, type=0;
     884             : 
     885           0 :   TString varVal;
     886           0 :   varVal="RMSs:RMSm";
     887             :   //
     888           0 :  TString varCut;
     889           0 :   varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type);
     890             :   //
     891           0 :   Int_t entries = tree->Draw(varVal.Data(),varCut);
     892           0 :   Float_t px[20000], py[20000];
     893             :   //
     894           0 :   tree->Draw(varVal.Data(),varCut);
     895           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     896           0 :     px[ipoint]= tree->GetV2()[ipoint];
     897           0 :     py[ipoint]= tree->GetV1()[ipoint];
     898             :   }
     899           0 :   TLinearFitter fitter(2,"pol1");
     900           0 :   for (Int_t ipoint=0; ipoint<entries; ipoint++){
     901           0 :     Float_t val = py[ipoint];
     902           0 :     Float_t err = fRatio*px[ipoint];
     903           0 :     Double_t x[4];
     904           0 :     x[0] = px[ipoint];
     905           0 :     if (err>0) fitter.AddPoint(x,val,err);
     906           0 :   }
     907           0 :   fitter.Eval();
     908           0 :   param0[0]= fitter.GetParameter(0);
     909           0 :   param0[1]= fitter.GetParameter(1);
     910           0 : }
     911             : 
     912             : 
     913             : 
     914             : Float_t  AliTPCClusterParam::GetError0(Int_t dim, Int_t type, Float_t z, Float_t angle) const {
     915             :   ///
     916             : 
     917             :   Float_t value=0;
     918           0 :   value += fParamS0[dim][type][0];
     919           0 :   value += fParamS0[dim][type][1]*z;
     920           0 :   value += fParamS0[dim][type][2]*angle*angle;
     921           0 :   value  = TMath::Sqrt(TMath::Abs(value));
     922           0 :   return value;
     923             : }
     924             : 
     925             : 
     926             : Float_t  AliTPCClusterParam::GetError0Par(Int_t dim, Int_t type, Float_t z, Float_t angle) const {
     927             :   ///
     928             : 
     929             :   Float_t value=0;
     930      428136 :   value += fParamS0Par[dim][type][0];
     931      214068 :   value += fParamS0Par[dim][type][1]*z;
     932      214068 :   value += fParamS0Par[dim][type][2]*angle*angle;
     933      214068 :   value += fParamS0Par[dim][type][3]*z*z;
     934      214068 :   value += fParamS0Par[dim][type][4]*angle*angle*angle*angle;
     935      214068 :   value += fParamS0Par[dim][type][5]*z*angle*angle;
     936      214068 :   value  = TMath::Sqrt(TMath::Abs(value));
     937      214068 :   return value;
     938             : }
     939             : 
     940             : 
     941             : 
     942             : Float_t  AliTPCClusterParam::GetError1(Int_t dim, Int_t type, Float_t z, Float_t angle) const {
     943             :   ///
     944             : 
     945             :   Float_t value=0;
     946             :   Float_t length=0.75;
     947           0 :   if (type==1) length=1;
     948           0 :   if (type==2) length=1.5;
     949           0 :   value += fParamS1[dim][0];
     950           0 :   value += fParamS1[dim][1]*z/length;
     951           0 :   value += fParamS1[dim][2]*angle*angle*length;
     952           0 :   value  = TMath::Sqrt(TMath::Abs(value));
     953           0 :   return value;
     954             : }
     955             : 
     956             : Float_t  AliTPCClusterParam::GetErrorQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const {
     957             :   ///
     958             : 
     959             :   Float_t value=0;
     960           0 :   value += fParamSQ[dim][type][0];
     961           0 :   value += fParamSQ[dim][type][1]*z;
     962           0 :   value += fParamSQ[dim][type][2]*angle*angle;
     963           0 :   value += fParamSQ[dim][type][3]*z/Qmean;
     964           0 :   value += fParamSQ[dim][type][4]*angle*angle/Qmean;
     965           0 :   value  = TMath::Sqrt(TMath::Abs(value));
     966           0 :   return value;
     967             : 
     968             : 
     969             : }
     970             : 
     971             : Float_t  AliTPCClusterParam::GetErrorQPar(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const {
     972             :   ///
     973             : 
     974             :   Float_t value=0;
     975           0 :   value += fParamSQPar[dim][type][0];
     976           0 :   value += fParamSQPar[dim][type][1]*z;
     977           0 :   value += fParamSQPar[dim][type][2]*angle*angle;
     978           0 :   value += fParamSQPar[dim][type][3]*z*z;
     979           0 :   value += fParamSQPar[dim][type][4]*angle*angle*angle*angle;
     980           0 :   value += fParamSQPar[dim][type][5]*z*angle*angle;
     981           0 :   value += fParamSQPar[dim][type][6]*z/Qmean;
     982           0 :   value += fParamSQPar[dim][type][7]*angle*angle/Qmean;
     983           0 :   value  = TMath::Sqrt(TMath::Abs(value));
     984           0 :   return value;
     985             : 
     986             : 
     987             : }
     988             : 
     989             : Float_t  AliTPCClusterParam::GetErrorQParScaled(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const {
     990             :   ///
     991             : 
     992             :   Float_t value=0;
     993           0 :   value += fParamSQPar[dim][type][0];
     994           0 :   value += fParamSQPar[dim][type][1]*z;
     995           0 :   value += fParamSQPar[dim][type][2]*angle*angle;
     996           0 :   value += fParamSQPar[dim][type][3]*z*z;
     997           0 :   value += fParamSQPar[dim][type][4]*angle*angle*angle*angle;
     998           0 :   value += fParamSQPar[dim][type][5]*z*angle*angle;
     999           0 :   value += fParamSQPar[dim][type][6]*z/Qmean;
    1000           0 :   value += fParamSQPar[dim][type][7]*angle*angle/Qmean;
    1001           0 :   Float_t valueMean = GetError0Par(dim,type,z,angle);
    1002           0 :   value -= 0.35*0.35*valueMean*valueMean;
    1003           0 :   value  = TMath::Sqrt(TMath::Abs(value));
    1004           0 :   return value;
    1005             : 
    1006             : 
    1007             : }
    1008             : 
    1009             : Float_t  AliTPCClusterParam::GetRMS0(Int_t dim, Int_t type, Float_t z, Float_t angle) const {
    1010             :   /// calculate mean RMS of cluster - z,angle - parameters for each pad and dimension separatelly
    1011             : 
    1012             :   Float_t value=0;
    1013      952520 :   value += fParamRMS0[dim][type][0];
    1014      476260 :   value += fParamRMS0[dim][type][1]*z;
    1015      476260 :   value += fParamRMS0[dim][type][2]*angle*angle;
    1016      476260 :   value  = TMath::Sqrt(TMath::Abs(value));
    1017      476260 :   return value;
    1018             : }
    1019             : 
    1020             : Float_t  AliTPCClusterParam::GetRMS1(Int_t dim, Int_t type, Float_t z, Float_t angle) const {
    1021             :   /// calculate mean RMS of cluster - z,angle - pad length scalling
    1022             : 
    1023             :   Float_t value=0;
    1024             :   Float_t length=0.75;
    1025           0 :   if (type==1) length=1;
    1026           0 :   if (type==2) length=1.5;
    1027           0 :   if (type==0){
    1028           0 :     value += fParamRMS1[dim][0];
    1029           0 :   }else{
    1030           0 :     value += fParamRMS1[dim][1];
    1031             :   }
    1032           0 :   value += fParamRMS1[dim][2]*z;
    1033           0 :   value += fParamRMS1[dim][3]*angle*angle*length*length;
    1034           0 :   value  = TMath::Sqrt(TMath::Abs(value));
    1035           0 :   return value;
    1036             : }
    1037             : 
    1038             : Float_t  AliTPCClusterParam::GetRMSQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const {
    1039             :   /// calculate mean RMS of cluster - z,angle, Q dependence
    1040             : 
    1041             :   Float_t value=0;
    1042           0 :   value += fParamRMSQ[dim][type][0];
    1043           0 :   value += fParamRMSQ[dim][type][1]*z;
    1044           0 :   value += fParamRMSQ[dim][type][2]*angle*angle;
    1045           0 :   value += fParamRMSQ[dim][type][3]*z/Qmean;
    1046           0 :   value += fParamRMSQ[dim][type][4]*angle*angle/Qmean;
    1047           0 :   value  = TMath::Sqrt(TMath::Abs(value));
    1048           0 :   return value;
    1049             : }
    1050             : 
    1051             : Float_t  AliTPCClusterParam::GetRMSSigma(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const {
    1052             :   /// calculates RMS of signal shape fluctuation
    1053             : 
    1054           0 :   Float_t mean = GetRMSQ(dim,type,z,angle,Qmean);
    1055           0 :   Float_t value  = fRMSSigmaFit[dim][type][0];
    1056           0 :   value+=  fRMSSigmaFit[dim][type][1]*mean;
    1057           0 :   return value;
    1058             : }
    1059             : 
    1060             : Float_t  AliTPCClusterParam::GetShapeFactor(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean, Float_t rmsL, Float_t rmsM) const {
    1061             :   /// calculates vallue - sigma distortion contribution
    1062             : 
    1063             :   Double_t value =0;
    1064             :   //
    1065           0 :   Float_t rmsMeanQ  = GetRMSQ(dim,type,z,angle,Qmean);
    1066           0 :   if (rmsL<rmsMeanQ) return value;
    1067             :   //
    1068           0 :   Float_t rmsSigma  = GetRMSSigma(dim,type,z,angle,Qmean);
    1069             :   //
    1070           0 :   if ((rmsM-rmsMeanQ)>2.0*(rmsSigma+fErrorRMSSys[dim])){
    1071             :     //1.5 sigma cut on mean
    1072           0 :     value+= rmsL*rmsL+2*rmsM*rmsM-3*rmsMeanQ*rmsMeanQ;
    1073           0 :   }else{
    1074           0 :     if ((rmsL-rmsMeanQ)>3.*(rmsSigma+fErrorRMSSys[dim])){
    1075             :       //3 sigma cut on local
    1076           0 :       value+= rmsL*rmsL-rmsMeanQ*rmsMeanQ;
    1077           0 :     }
    1078             :   }
    1079           0 :   return TMath::Sqrt(TMath::Abs(value));
    1080           0 : }
    1081             : 
    1082             : 
    1083             : 
    1084             : void AliTPCClusterParam::FitData(TTree * tree){
    1085             :   /// make fits for error param and shape param
    1086             : 
    1087           0 :   FitResol(tree);
    1088           0 :   FitRMS(tree);
    1089             : 
    1090           0 : }
    1091             : 
    1092             : void AliTPCClusterParam::FitResol(TTree * tree){
    1093             :   ///
    1094             : 
    1095           0 :   SetInstance(this);
    1096           0 :   for (Int_t idir=0;idir<2; idir++){
    1097           0 :     for (Int_t itype=0; itype<3; itype++){
    1098           0 :       Float_t param0[10];
    1099           0 :       Float_t error0[10];
    1100             :       // model error param
    1101           0 :       FitResol0(tree, idir, itype,param0,error0);
    1102           0 :       printf("\nResol\t%d\t%d\tchi2=%f\n",idir,itype,param0[3]);
    1103           0 :       printf("%f\t%f\t%f\n", param0[0],param0[1],param0[2]);
    1104           0 :       printf("%f\t%f\t%f\n", error0[0],error0[1],error0[2]);
    1105           0 :       for (Int_t ipar=0;ipar<4; ipar++){
    1106           0 :         fParamS0[idir][itype][ipar] = param0[ipar];
    1107           0 :         fErrorS0[idir][itype][ipar] = param0[ipar];
    1108             :       }
    1109             :       // error param with parabolic correction
    1110           0 :       FitResol0Par(tree, idir, itype,param0,error0);
    1111           0 :       printf("\nResolPar\t%d\t%d\tchi2=%f\n",idir,itype,param0[6]);
    1112           0 :       printf("%f\t%f\t%f\t%f\t%f\t%f\n", param0[0],param0[1],param0[2],param0[3],param0[4],param0[5]);
    1113           0 :       printf("%f\t%f\t%f\t%f\t%f\t%f\n", error0[0],error0[1],error0[2],error0[3],error0[4],error0[5]);
    1114           0 :       for (Int_t ipar=0;ipar<7; ipar++){
    1115           0 :         fParamS0Par[idir][itype][ipar] = param0[ipar];
    1116           0 :         fErrorS0Par[idir][itype][ipar] = param0[ipar];
    1117             :       }
    1118             :       //
    1119           0 :       FitResolQ(tree, idir, itype,param0,error0);
    1120           0 :       printf("\nResolQ\t%d\t%d\tchi2=%f\n",idir,itype,param0[5]);
    1121           0 :       printf("%f\t%f\t%f\t%f\t%f\n", param0[0],param0[1],param0[2],param0[3],param0[4]);
    1122           0 :       printf("%f\t%f\t%f\t%f\t%f\n", error0[0],error0[1],error0[2],error0[3],error0[4]);
    1123           0 :       for (Int_t ipar=0;ipar<6; ipar++){
    1124           0 :         fParamSQ[idir][itype][ipar] = param0[ipar];
    1125           0 :         fErrorSQ[idir][itype][ipar] = param0[ipar];
    1126             :       }
    1127             :       //
    1128           0 :       FitResolQPar(tree, idir, itype,param0,error0);
    1129           0 :       printf("\nResolQ\t%d\t%d\tchi2=%f\n",idir,itype,param0[8]);
    1130           0 :       printf("%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", param0[0],param0[1],param0[2],param0[3],param0[4],param0[5],param0[6],param0[7]);
    1131           0 :       printf("%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", error0[0],error0[1],error0[2],error0[3],error0[4],error0[5],error0[6],error0[7]);
    1132           0 :       for (Int_t ipar=0;ipar<9; ipar++){
    1133           0 :         fParamSQPar[idir][itype][ipar] = param0[ipar];
    1134           0 :         fErrorSQPar[idir][itype][ipar] = param0[ipar];
    1135             :       }
    1136           0 :     }
    1137             :   }
    1138             :   //
    1139           0 :   printf("Resol z-scaled\n");
    1140           0 :   for (Int_t idir=0;idir<2; idir++){
    1141           0 :     Float_t param0[4];
    1142           0 :     Float_t error0[4];
    1143           0 :     FitResol1(tree, idir,param0,error0);
    1144           0 :     printf("\nResol\t%d\tchi2=%f\n",idir,param0[3]);
    1145           0 :     printf("%f\t%f\t%f\n", param0[0],param0[1],param0[2]);
    1146           0 :     printf("%f\t%f\t%f\n", error0[0],error0[1],error0[2]);
    1147           0 :     for (Int_t ipar=0;ipar<4; ipar++){
    1148           0 :       fParamS1[idir][ipar] = param0[ipar];
    1149           0 :       fErrorS1[idir][ipar] = param0[ipar];
    1150             :     }
    1151           0 :   }
    1152             : 
    1153           0 :   for (Int_t idir=0;idir<2; idir++){
    1154           0 :     printf("\nDirection %d\n",idir);
    1155           0 :     printf("%d\t%f\t%f\t%f\n", -1,fParamS1[idir][0],fParamS1[idir][1],fParamS1[idir][2]);
    1156           0 :     for (Int_t itype=0; itype<3; itype++){
    1157             :       Float_t length=0.75;
    1158           0 :       if (itype==1) length=1;
    1159           0 :       if (itype==2) length=1.5;
    1160           0 :       printf("%d\t%f\t%f\t%f\n", itype,fParamS0[idir][itype][0],fParamS0[idir][itype][1]*TMath::Sqrt(length),fParamS0[idir][itype][2]/TMath::Sqrt(length));
    1161             :     }
    1162             :   }
    1163           0 : }
    1164             : 
    1165             : 
    1166             : 
    1167             : void AliTPCClusterParam::FitRMS(TTree * tree){
    1168             :   ///
    1169             : 
    1170           0 :   SetInstance(this);
    1171           0 :   for (Int_t idir=0;idir<2; idir++){
    1172           0 :     for (Int_t itype=0; itype<3; itype++){
    1173           0 :       Float_t param0[6];
    1174           0 :       Float_t error0[6];
    1175           0 :       FitRMS0(tree, idir, itype,param0,error0);
    1176           0 :       printf("\nRMS\t%d\t%d\tchi2=%f\n",idir,itype,param0[3]);
    1177           0 :       printf("%f\t%f\t%f\n", param0[0],param0[1],param0[2]);
    1178           0 :       printf("%f\t%f\t%f\n", error0[0],error0[1],error0[2]);
    1179           0 :       for (Int_t ipar=0;ipar<4; ipar++){
    1180           0 :         fParamRMS0[idir][itype][ipar] = param0[ipar];
    1181           0 :         fErrorRMS0[idir][itype][ipar] = param0[ipar];
    1182             :       }
    1183           0 :       FitRMSQ(tree, idir, itype,param0,error0);
    1184           0 :       printf("\nRMSQ\t%d\t%d\tchi2=%f\n",idir,itype,param0[5]);
    1185           0 :       printf("%f\t%f\t%f\t%f\t%f\n", param0[0],param0[1],param0[2],param0[3],param0[4]);
    1186           0 :       printf("%f\t%f\t%f\t%f\t%f\n", error0[0],error0[1],error0[2],error0[3],error0[4]);
    1187           0 :       for (Int_t ipar=0;ipar<6; ipar++){
    1188           0 :         fParamRMSQ[idir][itype][ipar] = param0[ipar];
    1189           0 :         fErrorRMSQ[idir][itype][ipar] = param0[ipar];
    1190             :       }
    1191           0 :     }
    1192             :   }
    1193             :   //
    1194           0 :   printf("RMS z-scaled\n");
    1195           0 :   for (Int_t idir=0;idir<2; idir++){
    1196           0 :     Float_t param0[5];
    1197           0 :     Float_t error0[5];
    1198           0 :     FitRMS1(tree, idir,param0,error0);
    1199           0 :     printf("\nRMS\t%d\tchi2=%f\n",idir,param0[4]);
    1200           0 :     printf("%f\t%f\t%f\t%f\n", param0[0],param0[1],param0[2], param0[3]);
    1201           0 :     printf("%f\t%f\t%f\t%f\n", error0[0],error0[1],error0[2], error0[3]);
    1202           0 :     for (Int_t ipar=0;ipar<5; ipar++){
    1203           0 :       fParamRMS1[idir][ipar] = param0[ipar];
    1204           0 :       fErrorRMS1[idir][ipar] = param0[ipar];
    1205             :     }
    1206           0 :   }
    1207             : 
    1208           0 :   for (Int_t idir=0;idir<2; idir++){
    1209           0 :     printf("\nDirection %d\n",idir);
    1210           0 :     printf("%d\t%f\t%f\t%f\t%f\n", -1,fParamRMS1[idir][0],fParamRMS1[idir][1],fParamRMS1[idir][2], fParamRMS1[idir][3]);
    1211           0 :     for (Int_t itype=0; itype<3; itype++){
    1212             :       Float_t length=0.75;
    1213           0 :       if (itype==1) length=1;
    1214           0 :       if (itype==2) length=1.5;
    1215           0 :       if (itype==0) printf("%d\t%f\t\t\t%f\t%f\n", itype,fParamRMS0[idir][itype][0],fParamRMS0[idir][itype][1],fParamRMS0[idir][itype][2]/length);
    1216           0 :       if (itype>0) printf("%d\t\t\t%f\t%f\t%f\n", itype,fParamRMS0[idir][itype][0],fParamRMS0[idir][itype][1],fParamRMS0[idir][itype][2]/length);
    1217             :     }
    1218             :   }
    1219             :   //
    1220             :   // Fit RMS sigma
    1221             :   //
    1222           0 :   printf("RMS fluctuation  parameterization \n");
    1223           0 :   for (Int_t idir=0;idir<2; idir++){
    1224           0 :     for (Int_t itype=0; itype<3; itype++){
    1225           0 :       Float_t param0[5];
    1226           0 :       Float_t error0[5];
    1227           0 :       FitRMSSigma(tree, idir,itype,param0,error0);
    1228           0 :       printf("\t%d\t%d\t%f\t%f\n", idir, itype, param0[0],param0[1]);
    1229           0 :       for (Int_t ipar=0;ipar<2; ipar++){
    1230           0 :         fRMSSigmaFit[idir][itype][ipar] = param0[ipar];
    1231             :       }
    1232           0 :     }
    1233             :   }
    1234             :   //
    1235             :   // store systematic error end RMS fluctuation parameterization
    1236             :   //
    1237           0 :   TH1F hratio("hratio","hratio",100,-0.1,0.1);
    1238           0 :   tree->Draw("(RMSm-AliTPCClusterParam::SGetRMSQ(Dim,Pad,Zm,AngleM,QMean))/RMSm>>hratio","Dim==0&&QMean>0");
    1239           0 :   fErrorRMSSys[0] = hratio.GetRMS();
    1240           0 :   tree->Draw("(RMSm-AliTPCClusterParam::SGetRMSQ(Dim,Pad,Zm,AngleM,QMean))/RMSm>>hratio","Dim==1&&QMean>0");
    1241           0 :   fErrorRMSSys[1] = hratio.GetRMS();
    1242           0 :   TH1F hratioR("hratioR","hratioR",100,0,0.2);
    1243           0 :   tree->Draw("RMSs/RMSm>>hratioR","Dim==0&&QMean>0");
    1244           0 :   fRMSSigmaRatio[0][0]=hratioR.GetMean();
    1245           0 :   fRMSSigmaRatio[0][1]=hratioR.GetRMS();
    1246           0 :   tree->Draw("RMSs/RMSm>>hratioR","Dim==1&&QMean>0");
    1247           0 :   fRMSSigmaRatio[1][0]=hratioR.GetMean();
    1248           0 :   fRMSSigmaRatio[1][1]=hratioR.GetRMS();
    1249           0 : }
    1250             : 
    1251             : void AliTPCClusterParam::Test(TTree * tree, const char *output){
    1252             :   /// Draw standard quality histograms to output file
    1253             : 
    1254           0 :   SetInstance(this);
    1255           0 :   TFile f(output,"recreate");
    1256           0 :   f.cd();
    1257             :   //
    1258             :   // 1D histograms - resolution
    1259             :   //
    1260           0 :   for (Int_t idim=0; idim<2; idim++){
    1261           0 :     for (Int_t ipad=0; ipad<3; ipad++){
    1262           0 :       char hname1[300];
    1263           0 :       char hcut1[300];
    1264           0 :       char hexp1[300];
    1265             :       //
    1266           0 :       snprintf(hname1,300,"Delta0 Dir %d Pad %d",idim,ipad);
    1267           0 :       snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad);
    1268           0 :       snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1);
    1269           0 :       TH1F  his1DRel0(hname1, hname1, 100,-0.2, 0.2);
    1270           0 :       snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad);
    1271           0 :       tree->Draw(hexp1,hcut1,"");
    1272           0 :       his1DRel0.Write();
    1273             :       //
    1274           0 :       snprintf(hname1,300,"Delta0Par Dir %d Pad %d",idim,ipad);
    1275           0 :       snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad);
    1276           0 :       snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1);
    1277           0 :       TH1F  his1DRel0Par(hname1, hname1, 100,-0.2, 0.2);
    1278           0 :       snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad);
    1279           0 :       tree->Draw(hexp1,hcut1,"");
    1280           0 :       his1DRel0Par.Write();
    1281             :       //
    1282           0 :     }
    1283             :   }
    1284             :   //
    1285             :   // 2D histograms - resolution
    1286             :   //
    1287           0 :   for (Int_t idim=0; idim<2; idim++){
    1288           0 :     for (Int_t ipad=0; ipad<3; ipad++){
    1289           0 :       char hname1[300];
    1290           0 :       char hcut1[300];
    1291           0 :       char hexp1[300];
    1292             :       //
    1293           0 :       snprintf(hname1,300,"2DDelta0 Dir %d Pad %d",idim,ipad);
    1294           0 :       snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad);
    1295           0 :       snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1);
    1296           0 :       TProfile2D  profDRel0(hname1, hname1, 6,0,250,6,0,1);
    1297           0 :       snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad);
    1298           0 :       tree->Draw(hexp1,hcut1,"");
    1299           0 :       profDRel0.Write();
    1300             :       //
    1301           0 :       snprintf(hname1,300,"2DDelta0Par Dir %d Pad %d",idim,ipad);
    1302           0 :       snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad);
    1303           0 :       snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1);
    1304           0 :       TProfile2D profDRel0Par(hname1, hname1,6,0,250,6,0,1);
    1305           0 :       snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad);
    1306           0 :       tree->Draw(hexp1,hcut1,"");
    1307           0 :       profDRel0Par.Write();
    1308             :       //
    1309           0 :     }
    1310             :   }
    1311           0 : }
    1312             : 
    1313             : 
    1314             : 
    1315             : void AliTPCClusterParam::Print(Option_t* /*option*/) const{
    1316             :   /// Print param Information
    1317             : 
    1318             :   //
    1319             :   // Error parameterization
    1320             :   //
    1321           0 :   printf("\nResolution Scaled factors\n");
    1322           0 :   printf("Dir\tPad\tP0\t\tP1\t\tP2\t\tchi2\n");
    1323           0 :   printf("Y\tall\t%f\t%f\t%f\t%f\n", TMath::Sqrt(TMath::Abs(fParamS1[0][0])),TMath::Sqrt(TMath::Abs(fParamS1[0][1])),
    1324           0 :          TMath::Sqrt(TMath::Abs(fParamS1[0][2])),TMath::Sqrt(TMath::Abs(fParamS1[0][3])));
    1325           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1326             :     Float_t length=0.75;
    1327           0 :     if (ipad==1) length=1;
    1328           0 :     if (ipad==2) length=1.5;
    1329           0 :     printf("\t%d\t%f\t%f\t%f\t%f\n", ipad,
    1330           0 :            TMath::Sqrt(TMath::Abs(fParamS0[0][ipad][0])),
    1331           0 :            TMath::Sqrt(TMath::Abs(fParamS0[0][ipad][1]*length)),
    1332           0 :            TMath::Sqrt(TMath::Abs(fParamS0[0][ipad][2]/length)),
    1333           0 :            TMath::Sqrt(TMath::Abs(fParamS0[0][ipad][3])));
    1334             :   }
    1335           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1336             :     Float_t length=0.75;
    1337           0 :     if (ipad==1) length=1;
    1338           0 :     if (ipad==2) length=1.5;
    1339           0 :     printf("\t%dPar\t%f\t%f\t%f\t%f\n", ipad,
    1340           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[0][ipad][0])),
    1341           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[0][ipad][1]*length)),
    1342           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[0][ipad][2]/length)),
    1343           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[0][ipad][6])));
    1344             :   }
    1345           0 :   printf("Z\tall\t%f\t%f\t%f\t%f\n", TMath::Sqrt(TMath::Abs(fParamS1[1][0])),TMath::Sqrt(fParamS1[1][1]),
    1346           0 :          TMath::Sqrt(fParamS1[1][2]), TMath::Sqrt(fParamS1[1][3]));
    1347             : 
    1348           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1349             :     Float_t length=0.75;
    1350           0 :     if (ipad==1) length=1;
    1351           0 :     if (ipad==2) length=1.5;
    1352           0 :     printf("\t%d\t%f\t%f\t%f\t%f\n", ipad,
    1353           0 :            TMath::Sqrt(TMath::Abs(fParamS0[1][ipad][0])),
    1354           0 :            TMath::Sqrt(TMath::Abs(fParamS0[1][ipad][1]*length)),
    1355           0 :            TMath::Sqrt(TMath::Abs(fParamS0[1][ipad][2]/length)),
    1356           0 :            TMath::Sqrt(TMath::Abs(fParamS0[1][ipad][3])));
    1357             :   }
    1358           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1359             :     Float_t length=0.75;
    1360           0 :     if (ipad==1) length=1;
    1361           0 :     if (ipad==2) length=1.5;
    1362           0 :     printf("\t%dPar\t%f\t%f\t%f\t%f\n", ipad,
    1363           0 :            TMath::Sqrt(TMath::Abs(TMath::Abs(fParamS0Par[1][ipad][0]))),
    1364           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[1][ipad][1]*length)),
    1365           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[1][ipad][2]/length)),
    1366           0 :            TMath::Sqrt(TMath::Abs(fParamS0Par[1][ipad][6])));
    1367             :   }
    1368             : 
    1369             :   //
    1370             :   // RMS scaling
    1371             :   //
    1372           0 :   printf("\n");
    1373           0 :   printf("\nRMS Scaled factors\n");
    1374           0 :   printf("Dir\tPad\tP00\t\tP01\t\tP1\t\tP2\t\tchi2\n");
    1375           0 :   printf("Y\tall\t%f\t%f\t%f\t%f\t%f\n",
    1376           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[0][0])),
    1377           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[0][1])),
    1378           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[0][2])),
    1379           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[0][3])),
    1380           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[0][4])));
    1381           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1382             :     Float_t length=0.75;
    1383           0 :     if (ipad==1) length=1;
    1384           0 :     if (ipad==2) length=1.5;
    1385           0 :     if (ipad==0){
    1386           0 :       printf("\t%d\t%f\t%f\t%f\t%f\t%f\n", ipad,
    1387           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][0])),
    1388             :              0.,
    1389           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][1])),
    1390           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][2]/(length*length))),
    1391           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][3])));
    1392           0 :     }else{
    1393           0 :       printf("\t%d\t%f\t%f\t%f\t%f\t%f\n", ipad,
    1394             :              0.,
    1395             :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][0])),
    1396             :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][1])),
    1397             :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][2]/(length*length))),
    1398             :              TMath::Sqrt(TMath::Abs(fParamRMS0[0][ipad][3])));
    1399             :     }
    1400             :   }
    1401           0 :   printf("\n");
    1402           0 :   printf("Z\tall\t%f\t%f\t%f\t%f\t%f\n",
    1403           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[1][0])),
    1404           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[1][1])),
    1405           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[1][2])),
    1406           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[1][3])),
    1407           0 :          TMath::Sqrt(TMath::Abs(fParamRMS1[1][4])));
    1408           0 :   for (Int_t ipad=0; ipad<3; ipad++){
    1409             :     Float_t length=0.75;
    1410           0 :     if (ipad==1) length=1;
    1411           0 :     if (ipad==2) length=1.5;
    1412           0 :     if (ipad==0){
    1413           0 :       printf("\t%d\t%f\t%f\t%f\t%f\t%f\n", ipad,
    1414           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][0])),
    1415             :              0.,
    1416           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][1])),
    1417           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][2]/(length*length))),
    1418           0 :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][3])));
    1419           0 :     }else{
    1420           0 :       printf("\t%d\t%f\t%f\t%f\t%f\t%f\n", ipad,
    1421             :              0.,
    1422             :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][0])),
    1423             :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][1])),
    1424             :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][2]/(length*length))),
    1425             :              TMath::Sqrt(TMath::Abs(fParamRMS0[1][ipad][3])));
    1426             :     }
    1427             :   }
    1428           0 :   printf("\ndEdx  correction matrix used in GetQnormCorr\n");
    1429           0 :   fQNormCorr->Print();
    1430             : 
    1431           0 : }
    1432             : 
    1433             : 
    1434             : 
    1435             : 
    1436             : 
    1437             : Float_t AliTPCClusterParam::Qnorm(Int_t ipad, Int_t itype, Float_t dr, Float_t ty, Float_t tz){
    1438             :   /// get Q normalization
    1439             :   /// type - 0 Qtot 1 Qmax
    1440             :   /// ipad - 0 (0.75 cm) ,1 (1 cm), 2 (1.5 cm)
    1441             :   ///
    1442             :   /// expession formula - TString *strq0 = toolkit.FitPlane(chain,"dedxQ.fElements[2]","dr++ty++tz++dr*ty++dr*tz++++dr*dr++ty*tz++ty^2++tz^2","IPad==0",chi2,npoints,param,covar,0,100000);
    1443             : 
    1444           0 :   if (fQNorm==0) return 0;
    1445           0 :   TVectorD * norm = (TVectorD*)fQNorm->At(3*itype+ipad);
    1446           0 :   if (!norm) return 0;
    1447             :   TVectorD &no  = *norm;
    1448             :   Float_t   res =
    1449           0 :     no[0]+
    1450           0 :     no[1]*dr+
    1451           0 :     no[2]*ty+
    1452           0 :     no[3]*tz+
    1453           0 :     no[4]*dr*ty+
    1454           0 :     no[5]*dr*tz+
    1455           0 :     no[6]*ty*tz+
    1456           0 :     no[7]*dr*dr+
    1457           0 :     no[8]*ty*ty+
    1458           0 :     no[9]*tz*tz;
    1459           0 :   res/=no[0];
    1460             :   return res;
    1461           0 : }
    1462             : 
    1463             : 
    1464             : 
    1465             : Float_t AliTPCClusterParam::QnormHis(Int_t ipad, Int_t itype, Float_t dr, Float_t p2, Float_t p3){
    1466             :   /// get Q normalization
    1467             :   /// type - 0 Qtot 1 Qmax
    1468             :   /// ipad - 0 (0.75 cm) ,1 (1 cm), 2 (1.5 cm)
    1469             : 
    1470           0 :   if (fQNormHis==0) return 0;
    1471           0 :   TH3F * norm = (TH3F*)fQNormHis->At(4*itype+ipad);
    1472           0 :   if (!norm) return 1;
    1473           0 :   p2=TMath::Abs(p2);
    1474           0 :   dr=TMath::Min(dr,Float_t(norm->GetXaxis()->GetXmax()-norm->GetXaxis()->GetBinWidth(0)));
    1475           0 :   dr=TMath::Max(dr,Float_t(norm->GetXaxis()->GetXmin()+norm->GetXaxis()->GetBinWidth(0)));
    1476             :   //
    1477           0 :   p2=TMath::Min(p2,Float_t(norm->GetYaxis()->GetXmax()-norm->GetYaxis()->GetBinWidth(0)));
    1478           0 :   p2=TMath::Max(p2,Float_t(norm->GetYaxis()->GetXmin()+norm->GetYaxis()->GetBinWidth(0)));
    1479             :   //
    1480           0 :   p3=TMath::Min(p3,Float_t(norm->GetZaxis()->GetXmax()-norm->GetZaxis()->GetBinWidth(0)));
    1481           0 :   p3=TMath::Max(p3,Float_t(norm->GetZaxis()->GetXmin()+norm->GetZaxis()->GetBinWidth(0)));
    1482             :   //
    1483           0 :   Double_t res = norm->GetBinContent(norm->FindBin(dr,p2,p3));
    1484           0 :   if (res==0) res = norm->GetBinContent(norm->FindBin(0.5,0.5,0.5));  // This is just hack - to be fixed entries without
    1485             : 
    1486           0 :   return res;
    1487           0 : }
    1488             : 
    1489             : 
    1490             : 
    1491             : void AliTPCClusterParam::SetQnorm(Int_t ipad, Int_t itype, const TVectorD *const norm){
    1492             :   /// set normalization
    1493             :   ///
    1494             :   /// type - 0 Qtot 1 Qmax
    1495             :   /// ipad - 0 (0.75 cm) ,1 (1 cm), 2 (1.5 cm)
    1496             : 
    1497           0 :   if (fQNorm==0) fQNorm = new TObjArray(6);
    1498           0 :   fQNorm->AddAt(new TVectorD(*norm), itype*3+ipad);
    1499           0 : }
    1500             : 
    1501             : void AliTPCClusterParam::ResetQnormCorr(){
    1502             :   ///
    1503             : 
    1504           0 :   if (!fQNormCorr) fQNormCorr= new TMatrixD(12,6);
    1505           0 :   for (Int_t irow=0;irow<12; irow++)
    1506           0 :     for (Int_t icol=0;icol<6; icol++){
    1507           0 :       (*fQNormCorr)(irow,icol)=1.;             // default - no correction
    1508           0 :       if (irow>5) (*fQNormCorr)(irow,icol)=0.; // default - no correction
    1509             :     }
    1510           0 : }
    1511             : 
    1512             : void AliTPCClusterParam::SetQnormCorr(Int_t ipad, Int_t itype, Int_t corrType, Float_t val, Int_t mode){
    1513             :   /// ipad        - pad type
    1514             :   /// itype       - 0- qtot 1-qmax
    1515             :   /// corrType    - 0 - s0y corr     - eff. PRF corr
    1516             :   /// - 1 - s0z corr     - eff. TRF corr
    1517             :   /// - 2 - d0y          - eff. diffusion correction y
    1518             :   /// - 3 - d0z          - eff. diffusion correction
    1519             :   /// - 4 - eff length   - eff.length - wire pitch + x diffsion
    1520             :   /// - 5 - pad type normalization
    1521             : 
    1522           0 :   if (!fQNormCorr) {
    1523           0 :     ResetQnormCorr();
    1524           0 :   }
    1525             :   //
    1526             :   // eff shap parameterization matrix
    1527             :   //
    1528             :   // rows
    1529             :   // itype*3+ipad  - itype=0 qtot itype=1 qmax ipad=0
    1530             :   //
    1531           0 :   if (mode==1) {
    1532             :     // mode introduced in 20.07.2014 - git describe ~ vAN-20140703-48-g3449a97 - to keep back compatibility with o
    1533           0 :     (*fQNormCorr)(itype*3+ipad, corrType) = val;  // set value
    1534           0 :     return;
    1535             :   }
    1536           0 :   if (itype<2) (*fQNormCorr)(itype*3+ipad, corrType) *= val;  // multiplicative correction
    1537           0 :   if (itype>=2) (*fQNormCorr)(itype*3+ipad, corrType)+= val;  // additive       correction
    1538           0 : }
    1539             : 
    1540             : Double_t  AliTPCClusterParam::GetQnormCorr(Int_t ipad, Int_t itype, Int_t corrType) const{
    1541             :   /// see AliTPCClusterParam::SetQnormCorr
    1542             : 
    1543     2387664 :   if (!fQNormCorr) return 0;
    1544     1193832 :   return  (*fQNormCorr)(itype*3+ipad, corrType);
    1545     1193832 : }
    1546             : 
    1547             : 
    1548             : Float_t AliTPCClusterParam::QnormPos(Int_t ipad,Bool_t isMax, Float_t pad, Float_t time, Float_t z, Float_t sy2, Float_t sz2, Float_t qm, Float_t qt){
    1549             :   /// Make Q normalization as function of following parameters
    1550             :   /// Fit parameters to be used in corresponding correction function extracted in the AliTPCclaibTracksGain - Taylor expansion
    1551             :   /// 1 - dp   - relative pad position
    1552             :   /// 2 - dt   - relative time position
    1553             :   /// 3 - di   - drift length (norm to 1);
    1554             :   /// 4 - dq0  - Tot/Max charge
    1555             :   /// 5 - dq1  - Max/Tot charge
    1556             :   /// 6 - sy   - sigma y - shape
    1557             :   /// 7 - sz   - sigma z - shape
    1558             : 
    1559             :   //The results can be visualized using the debug streamer information of the AliTPCcalibTracksGain -
    1560             :   // Following variable used - correspondance to the our variable conventions
    1561             :   //chain0->SetAlias("dp","((Cl.fPad-int(Cl.fPad)-0.5)/0.5)");
    1562           0 :   Double_t dp = ((pad-int(pad)-0.5)*2.);
    1563             :   //chain0->SetAlias("dt","((Cl.fTimeBin-int(Cl.fTimeBin)-0.5)/0.5)");
    1564           0 :   Double_t dt = ((time-int(time)-0.5)*2.);
    1565             :   //chain0->SetAlias("di","(sqrt(1.-abs(Cl.fZ)/250.))");
    1566           0 :   Double_t di = TMath::Sqrt(1-TMath::Abs(z)/250.);
    1567             :   //chain0->SetAlias("dq0","(0.2*(Cl.fQ+2)/(Cl.fMax+2))");
    1568           0 :   Double_t dq0 = 0.2*(qt+2.)/(qm+2.);
    1569             :   //chain0->SetAlias("dq1","(5*(Cl.fMax+2)/(Cl.fQ+2))");
    1570           0 :   Double_t dq1 = 5.*(qm+2.)/(qt+2.);
    1571             :   //chain0->SetAlias("sy","(0.32/sqrt(0.01^2+Cl.fSigmaY2))");
    1572           0 :   Double_t sy  = 0.32/TMath::Sqrt(0.01*0.01+sy2);
    1573             :   //chain0->SetAlias("sz","(0.32/sqrt(0.01^2+Cl.fSigmaZ2))");
    1574           0 :   Double_t sz  = 0.32/TMath::Sqrt(0.01*0.01+sz2);
    1575             :   //
    1576             :   //
    1577             :   //
    1578             :   TVectorD * pvec = 0;
    1579           0 :   if (isMax){
    1580           0 :     pvec = fPosQMnorm[ipad];
    1581           0 :   }else{
    1582           0 :     pvec = fPosQTnorm[ipad];
    1583             :   }
    1584             :   TVectorD &param = *pvec;
    1585             :   //
    1586             :   // Eval part  - in correspondance with fit part from debug streamer
    1587             :   //
    1588           0 :   Double_t result=param[0];
    1589             :   Int_t index =1;
    1590             :   //
    1591           0 :   result+=dp*param[index++];                               //1
    1592           0 :   result+=dt*param[index++];                               //2
    1593           0 :   result+=dp*dp*param[index++];                             //3
    1594           0 :   result+=dt*dt*param[index++];                             //4
    1595           0 :   result+=dt*dt*dt*param[index++];                             //5
    1596           0 :   result+=dp*dt*param[index++];                            //6
    1597           0 :   result+=dp*dt*dt*param[index++];                          //7
    1598           0 :   result+=(dq0)*param[index++];                            //8
    1599           0 :   result+=(dq1)*param[index++];                            //9
    1600             :   //
    1601             :   //
    1602           0 :   result+=dp*dp*(di)*param[index++];                        //10
    1603           0 :   result+=dt*dt*(di)*param[index++];                        //11
    1604           0 :   result+=dp*dp*sy*param[index++];                          //12
    1605           0 :   result+=dt*sz*param[index++];                          //13
    1606           0 :   result+=dt*dt*sz*param[index++];                          //14
    1607           0 :   result+=dt*dt*dt*sz*param[index++];                          //15
    1608             :   //
    1609           0 :   result+=dp*dp*1*sy*sz*param[index++];                     //16
    1610           0 :   result+=dt*sy*sz*param[index++];                       //17
    1611           0 :   result+=dt*dt*sy*sz*param[index++];                       //18
    1612           0 :   result+=dt*dt*dt*sy*sz*param[index++];                       //19
    1613             :   //
    1614           0 :   result+=dp*dp*(dq0)*param[index++];                       //20
    1615           0 :   result+=dt*1*(dq0)*param[index++];                       //21
    1616           0 :   result+=dt*dt*(dq0)*param[index++];                       //22
    1617           0 :   result+=dt*dt*dt*(dq0)*param[index++];                       //23
    1618             :   //
    1619           0 :   result+=dp*dp*(dq1)*param[index++];                       //24
    1620           0 :   result+=dt*(dq1)*param[index++];                       //25
    1621           0 :   result+=dt*dt*(dq1)*param[index++];                       //26
    1622           0 :   result+=dt*dt*dt*(dq1)*param[index++];                       //27
    1623             : 
    1624           0 :   if (result<0.75) result=0.75;
    1625           0 :   if (result>1.25) result=1.25;
    1626             : 
    1627           0 :   return result;
    1628             : 
    1629             : }
    1630             : 
    1631             : 
    1632             : 
    1633             : 
    1634             : 
    1635             : Float_t AliTPCClusterParam::PosCorrection(Int_t type, Int_t ipad,  Float_t pad, Float_t time, Float_t z, Float_t /*sy2*/, Float_t /*sz2*/, Float_t /*qm*/){
    1636             : 
    1637             :   /// Make postion correction
    1638             :   /// type - 0 - y correction
    1639             :   ///        1 - z correction
    1640             :   /// ipad - 0, 1, 2 - short, medium long pads
    1641             :   /// pad  - float pad number
    1642             :   /// time - float time bin number
    1643             :   ///    z - z of the cluster
    1644             : 
    1645             :   //
    1646             :   //chainres->SetAlias("dp","(-1+(Cl.fZ>0)*2)*((Cl.fPad-int(Cl.fPad))-0.5)");
    1647             :   //chainres->SetAlias("dt","(-1+(Cl.fZ>0)*2)*((Cl.fTimeBin-0.66-int(Cl.fTimeBin-0.66))-0.5)");
    1648             :   //chainres->SetAlias("sp","(sin(dp*pi)-dp*pi)");
    1649             :   //chainres->SetAlias("st","(sin(dt)-dt)");
    1650             :   //
    1651             :   //chainres->SetAlias("di","sqrt(1.-abs(Cl.fZ/250.))");
    1652             : 
    1653             :   //
    1654             :   // Derived variables
    1655             :   //
    1656           0 :   Double_t dp = (-1+(z>0)*2)*((pad-int(pad))-0.5);
    1657           0 :   Double_t dt = (-1+(z>0)*2)*((time-0.66-int(time-0.66))-0.5);
    1658           0 :   Double_t sp = (TMath::Sin(dp*TMath::Pi())-dp*TMath::Pi());
    1659           0 :   Double_t st = (TMath::Sin(dt)-dt);
    1660             :   //
    1661           0 :   Double_t di = TMath::Sqrt(TMath::Abs(1.-TMath::Abs(z/250.)));
    1662             :   //
    1663             :   //
    1664             :   //
    1665             :   TVectorD * pvec = 0;
    1666           0 :   if (type==0){
    1667           0 :     pvec = fPosYcor[ipad];
    1668           0 :   }else{
    1669           0 :     pvec = fPosZcor[ipad];
    1670             :   }
    1671             :   TVectorD &param = *pvec;
    1672             :   //
    1673             :   Double_t result=0;
    1674             :   Int_t index =1;
    1675             : 
    1676           0 :   if (type==0){
    1677             :     // y corr
    1678           0 :     result+=(dp)*param[index++];             //1
    1679           0 :     result+=(dp)*di*param[index++];          //2
    1680             :     //
    1681           0 :     result+=(sp)*param[index++];             //3
    1682           0 :     result+=(sp)*di*param[index++];          //4
    1683           0 :   }
    1684           0 :   if (type==1){
    1685           0 :     result+=(dt)*param[index++];             //1
    1686           0 :     result+=(dt)*di*param[index++];          //2
    1687             :     //
    1688           0 :     result+=(st)*param[index++];             //3
    1689           0 :     result+=(st)*di*param[index++];          //4
    1690           0 :   }
    1691           0 :   if (TMath::Abs(result)>0.05) return 0;
    1692           0 :   return result;
    1693           0 : }
    1694             : 
    1695             : 
    1696             : 
    1697             : Double_t  AliTPCClusterParam::GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1){
    1698             :   /// 2 D gaus convoluted with angular effect
    1699             :   /// See in mathematica:
    1700             :   /// Simplify[Integrate[Exp[-(x0-k0*xd)*(x0-k0*xd)/(2*s0*s0)-(x1-k1*xd)*(x1-k1*xd)/(2*s1*s1)]/(s0*s1),{xd,-1/2,1/2}]]
    1701             :   ///
    1702             :   /// TF1 f1("f1","AliTPCClusterParam::GaussConvolution(x,0,1,0,0.1,0.1)",-2,2)
    1703             :   /// TF2 f2("f2","AliTPCClusterParam::GaussConvolution(x,y,1,1,0.1,0.1)",-2,2,-2,2)
    1704             : 
    1705             :   const Double_t kEpsilon = 0.0001;
    1706    10436272 :   const Double_t twoPi = TMath::TwoPi();
    1707     5218136 :   const Double_t hnorm = 0.5/TMath::Sqrt(twoPi);
    1708     5218136 :   const Double_t sqtwo = TMath::Sqrt(2.);
    1709             : 
    1710     5218136 :   if ((TMath::Abs(k0)+TMath::Abs(k1))<kEpsilon*(s0+s1)){
    1711             :     // small angular effect
    1712       86986 :     Double_t val = TMath::Gaus(x0,0,s0)*TMath::Gaus(x1,0,s1)/(s0*s1*twoPi);
    1713             :     return val;
    1714             :   }
    1715     5131150 :   Double_t sigma2 = k1*k1*s0*s0+k0*k0*s1*s1;
    1716     5131150 :   Double_t sigma = TMath::Sqrt(sigma2);
    1717     5131150 :   Double_t exp0 = TMath::Exp(-(k1*x0-k0*x1)*(k1*x0-k0*x1)/(2.*sigma2));
    1718             :   //
    1719     5131150 :   Double_t sigmaErf =  1./(2.*s0*s1*sqtwo*sigma);
    1720     5131150 :   Double_t k0s1s1 = 2.*k0*s1*s1;
    1721     5131150 :   Double_t k1s0s0 = 2.*k1*s0*s0;
    1722     5131150 :   Double_t erf0 = AliMathBase::ErfFast((sigma2-k0s1s1*x0-k1s0s0*x1)*sigmaErf);
    1723     5131150 :   Double_t erf1 = AliMathBase::ErfFast((sigma2+k0s1s1*x0+k1s0s0*x1)*sigmaErf);
    1724     5131150 :   Double_t norm = hnorm/sigma;
    1725     5131150 :   Double_t val  = norm*exp0*(erf0+erf1);
    1726             :   return val;
    1727     5218136 : }
    1728             : 
    1729             : 
    1730             : Double_t  AliTPCClusterParam::GaussConvolutionTail(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1, Double_t tau){
    1731             :   /// 2 D gaus convoluted with angular effect and exponential tail in z-direction
    1732             :   /// tail integrated numerically
    1733             :   /// Integral normalized to one
    1734             :   /// Mean at 0
    1735             :   ///
    1736             :   /// TF1 f1t("f1t","AliTPCClusterParam::GaussConvolutionTail(0,x,0,0,0.5,0.5,0.9)",-5,5)
    1737             : 
    1738             :   Double_t sum =1, mean=0;
    1739             :   // the COG of exponent
    1740           0 :   for (Float_t iexp=0;iexp<5;iexp+=0.2){
    1741           0 :     mean+=iexp*TMath::Exp(-iexp/tau);
    1742           0 :     sum +=TMath::Exp(-iexp/tau);
    1743             :   }
    1744           0 :   mean/=sum;
    1745             :   //
    1746             :   sum = 1;
    1747           0 :   Double_t val = GaussConvolution(x0,x1+mean, k0, k1 , s0,s1);
    1748           0 :   for (Float_t iexp=0;iexp<5;iexp+=0.2){
    1749           0 :     val+=GaussConvolution(x0,x1+mean-iexp, k0, k1 , s0,s1)*TMath::Exp(-iexp/tau);
    1750           0 :     sum+=TMath::Exp(-iexp/tau);
    1751             :   }
    1752           0 :   return val/sum;
    1753             : }
    1754             : 
    1755             : Double_t  AliTPCClusterParam::GaussConvolutionGamma4(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1, Double_t tau){
    1756             :   /// 2 D gaus convoluted with angular effect and exponential tail in z-direction
    1757             :   /// tail integrated numerically
    1758             :   /// Integral normalized to one
    1759             :   /// Mean at 0
    1760             :   ///
    1761             :   /// TF1 f1g4("f1g4","AliTPCClusterParam::GaussConvolutionGamma4(0,x,0,0,0.5,0.2,1.6)",-5,5)
    1762             :   /// TF2 f2g4("f2g4","AliTPCClusterParam::GaussConvolutionGamma4(y,x,0,0,0.5,0.2,1.6)",-5,5,-5,5)
    1763             : 
    1764             :   Double_t sum =0, mean=0;
    1765             :   // the COG of G4
    1766           0 :   for (Float_t iexp=0;iexp<5;iexp+=0.2){
    1767           0 :     Double_t g4 = TMath::Exp(-4.*iexp/tau)*TMath::Power(iexp/tau,4.);
    1768           0 :     mean+=iexp*g4;
    1769           0 :     sum +=g4;
    1770             :   }
    1771           0 :   mean/=sum;
    1772             :   //
    1773             :   sum = 0;
    1774             :   Double_t val = 0;
    1775           0 :   for (Float_t iexp=0;iexp<5;iexp+=0.2){
    1776           0 :     Double_t g4 = TMath::Exp(-4.*iexp/tau)*TMath::Power(iexp/tau,4.);
    1777           0 :     val+=GaussConvolution(x0,x1+mean-iexp, k0, k1 , s0,s1)*g4;
    1778           0 :     sum+=g4;
    1779             :   }
    1780           0 :   return val/sum;
    1781             : }
    1782             : 
    1783             : Double_t  AliTPCClusterParam::QmaxCorrection(Int_t sector, Int_t row, Float_t cpad, Float_t ctime, Float_t ky, Float_t kz, Float_t rmsy0, Float_t rmsz0, Float_t effPad, Float_t effDiff){
    1784             :   /// cpad      - pad (y) coordinate
    1785             :   /// ctime     - time(z) coordinate
    1786             :   /// ky        - dy/dx
    1787             :   /// kz        - dz/dx
    1788             :   /// rmsy0     - RF width in pad units
    1789             :   /// rmsz0     - RF width in time bin  units
    1790             :   /// effLength - contibution of PRF and diffusion
    1791             :   /// effDiff   - overwrite diffusion
    1792             : 
    1793             :   // Response function aproximated by convolution of gaussian with angular effect (integral=1)
    1794             :   //
    1795             :   // Gaus width sy and sz is determined by RF width and diffusion
    1796             :   // Integral of Q is equal 1
    1797             :   // Q max is calculated at position cpad, ctime
    1798             :   // Example function:
    1799             :   //  TF1 f1("f1", "AliTPCClusterParam::QmaxCorrection(0,0.5,x,0,0,0.5,0.6)",0,1000)
    1800             :   //
    1801      101248 :   AliTPCParam * param   = AliTPCcalibDB::Instance()->GetParameters();
    1802       50624 :   Double_t padLength= param->GetPadPitchLength(sector,row);
    1803       50624 :   Double_t padWidth = param->GetPadPitchWidth(sector);
    1804       50624 :   Double_t zwidth   = param->GetZWidth();
    1805       50624 :   Double_t effLength= padLength+(param->GetWWPitch(0)+TMath::Sqrt(ctime*zwidth)*param->GetDiffT())*effPad;
    1806             : 
    1807             :   // diffusion in pad, time bin  units
    1808       50624 :   Double_t diffT=TMath::Sqrt(ctime*zwidth)*param->GetDiffT()/padWidth;
    1809       50624 :   Double_t diffL=TMath::Sqrt(ctime*zwidth)*param->GetDiffL()/zwidth;
    1810       50624 :   diffT*=effDiff;  //
    1811       50624 :   diffL*=effDiff;  //
    1812             :   //
    1813             :   // transform angular effect to pad units
    1814             :   //
    1815       50624 :   Double_t pky   = ky*effLength/padWidth;
    1816       50624 :   Double_t pkz   = kz*effLength/zwidth;
    1817             :   // position in pad unit
    1818       50624 :   Double_t py = (cpad+0.5)-TMath::Nint(cpad+0.5);
    1819       50624 :   Double_t pz = (ctime+0.5)-TMath::Nint(ctime+0.5);
    1820             :   //
    1821             :   //
    1822       50624 :   Double_t sy = TMath::Sqrt(rmsy0*rmsy0+diffT*diffT);
    1823       50624 :   Double_t sz = TMath::Sqrt(rmsz0*rmsz0+diffL*diffL);
    1824             :   //return GaussConvolutionGamma4(py,pz, pky,pkz,sy,sz,tau);
    1825       50624 :   Double_t length = padLength*TMath::Sqrt(1+ky*ky+kz*kz);
    1826       50624 :   return GaussConvolution(py,pz, pky,pkz,sy,sz)*length;
    1827             : }
    1828             : 
    1829             : Double_t  AliTPCClusterParam::QtotCorrection(Int_t sector, Int_t row, Float_t cpad, Float_t ctime, Float_t ky, Float_t kz, Float_t rmsy0, Float_t rmsz0,  Float_t qtot, Float_t thr, Float_t effPad, Float_t effDiff){
    1830             :   /// cpad      - pad (y) coordinate
    1831             :   /// ctime     - time(z) coordinate
    1832             :   /// ky        - dy/dx
    1833             :   /// kz        - dz/dx
    1834             :   /// rmsy0     - RF width in pad units
    1835             :   /// rmsz0     - RF width in time bin  units
    1836             :   /// qtot      - the sum of signal in cluster - without thr correction
    1837             :   /// thr       - threshold
    1838             :   /// effLength - contibution of PRF and diffusion
    1839             :   /// effDiff   - overwrite diffusion
    1840             : 
    1841             :   // Response function aproximated by convolution of gaussian with angular effect (integral=1)
    1842             :   //
    1843             :   // Gaus width sy and sz is determined by RF width and diffusion
    1844             :   // Integral of Q is equal 1
    1845             :   // Q max is calculated at position cpad, ctime
    1846             :   //
    1847             :   //
    1848             :   //
    1849      164048 :   AliTPCParam * param   = AliTPCcalibDB::Instance()->GetParameters();
    1850       82024 :   Double_t padLength= param->GetPadPitchLength(sector,row);
    1851       82024 :   Double_t padWidth = param->GetPadPitchWidth(sector);
    1852       82024 :   Double_t zwidth   = param->GetZWidth();
    1853       82024 :   Double_t effLength= padLength+(param->GetWWPitch(0)+TMath::Sqrt(ctime*zwidth)*param->GetDiffT())*effPad;
    1854             :   //
    1855             :   // diffusion in pad units
    1856       82024 :   Double_t diffT=TMath::Sqrt(ctime*zwidth)*param->GetDiffT()/padWidth;
    1857       82024 :   Double_t diffL=TMath::Sqrt(ctime*zwidth)*param->GetDiffL()/zwidth;
    1858       82024 :   diffT*=effDiff;  //
    1859       82024 :   diffL*=effDiff;  //
    1860             :   //
    1861             :   // transform angular effect to pad units
    1862       82024 :   Double_t pky   = ky*effLength/padWidth;
    1863       82024 :   Double_t pkz   = kz*effLength/zwidth;
    1864             :   // position in pad unit
    1865             :   //
    1866       82024 :   Double_t py = (cpad+0.5)-TMath::Nint(cpad+0.5);
    1867       82024 :   Double_t pz = (ctime+0.5)-TMath::Nint(ctime+0.5);
    1868             :   //
    1869       82024 :   Double_t sy = TMath::Sqrt(rmsy0*rmsy0+diffT*diffT);
    1870       82024 :   Double_t sz = TMath::Sqrt(rmsz0*rmsz0+diffL*diffL);
    1871             :   //
    1872             :   //
    1873             :   //
    1874             :   Double_t sumAll=0,sumThr=0;
    1875             :   //
    1876             :   Double_t corr =1;
    1877       82024 :   Double_t qnorm=qtot;
    1878     1312384 :   for (Float_t iy=-3;iy<=3;iy+=1.)
    1879    11483360 :     for (Float_t iz=-4;iz<=4;iz+=1.){
    1880             :       //      Double_t val = GaussConvolutionGamma4(py-iy,pz-iz, pky,pkz, sy,sz,tau);
    1881     5167512 :       Double_t val = GaussConvolution(py-iy,pz-iz, pky,pkz, sy,sz);
    1882     5167512 :       Double_t qlocal =qnorm*val;
    1883     7382160 :       if (TMath::Abs(iy)<1.5&&TMath::Abs(iz)<1.5){
    1884      738216 :         sumThr+=qlocal;   // Virtual charge used in cluster finder
    1885      738216 :       }
    1886             :       else{
    1887     5392512 :         if (qlocal>thr && TMath::Abs(iz)<2.5&&TMath::Abs(iy)<2.5) sumThr+=qlocal;
    1888             :       }
    1889     5167512 :       sumAll+=qlocal;
    1890             :     }
    1891       82024 :   if (sumAll>0&&sumThr>0) {
    1892       82024 :     corr=(sumThr)/sumAll;
    1893       82024 :   }
    1894             :   //
    1895       82024 :   Double_t length = padLength*TMath::Sqrt(1+ky*ky+kz*kz);
    1896       82024 :   return corr*length;
    1897             : }
    1898             : 
    1899             : 
    1900             : 
    1901             : void AliTPCClusterParam::SetWaveCorrectionMap( THnBase *Map)
    1902             : {
    1903             :   /// Set Correction Map for Y
    1904             : 
    1905           0 :   delete fWaveCorrectionMap;
    1906           0 :   fWaveCorrectionMap = 0;
    1907           0 :   fWaveCorrectionMirroredPad = kFALSE;
    1908           0 :   fWaveCorrectionMirroredZ = kFALSE;
    1909           0 :   fWaveCorrectionMirroredAngle = kFALSE;
    1910           0 :   if( Map ){
    1911           0 :     fWaveCorrectionMap = dynamic_cast<THnBase*>( Map->Clone(Map->GetName()));
    1912           0 :     if( fWaveCorrectionMap ){
    1913           0 :       fWaveCorrectionMirroredPad   = ( fWaveCorrectionMap->GetAxis(3)->FindFixBin(0.5)<=1 );   // Pad axis is mirrored at 0.5
    1914           0 :       fWaveCorrectionMirroredZ     = ( fWaveCorrectionMap->GetAxis(1)->FindFixBin(0.0)<=1); // Z axis is mirrored at 0
    1915           0 :       fWaveCorrectionMirroredAngle = ( fWaveCorrectionMap->GetAxis(4)->FindFixBin(0.0)<=1 );   // Angle axis is mirrored at 0
    1916           0 :     }
    1917             :   }
    1918           0 : }
    1919             : 
    1920             : void AliTPCClusterParam::SetResolutionYMap( THnBase *Map)
    1921             : {
    1922             :   /// Set Resolution Map for Y
    1923             : 
    1924           0 :   delete fResolutionYMap;
    1925           0 :   fResolutionYMap = 0;
    1926           0 :   if( Map ){
    1927           0 :     fResolutionYMap = dynamic_cast<THnBase*>( Map->Clone(Map->GetName()));
    1928           0 :   }
    1929           0 : }
    1930             : 
    1931             : Float_t AliTPCClusterParam::GetWaveCorrection(Int_t Type, Float_t Z, Int_t QMax, Float_t Pad, Float_t angleY ) const
    1932             : {
    1933             :   /// Correct Y cluster coordinate using a map
    1934             : 
    1935      297744 :   if( !fWaveCorrectionMap ) return 0;
    1936             :   Bool_t swapY = kFALSE;
    1937           0 :   Pad = Pad-(Int_t)Pad;
    1938             : 
    1939           0 :   if( TMath::Abs(Pad-0.5)<1.e-8 ){// one pad clusters a stored in underflow bins
    1940             :     Pad = -1.;
    1941           0 :   } else {
    1942           0 :     if( fWaveCorrectionMirroredPad && (Pad<0.5) ){ // cog axis is mirrored at 0.5
    1943             :         swapY = !swapY;
    1944           0 :         Pad = 1.0 - Pad;
    1945           0 :     }
    1946             :   }
    1947             : 
    1948           0 :   if( fWaveCorrectionMirroredZ && (Z<0) ){ // Z axis is mirrored at 0
    1949           0 :     swapY = !swapY;
    1950           0 :     Z = -Z;
    1951           0 :   }
    1952             : 
    1953           0 :   if( fWaveCorrectionMirroredAngle && (angleY<0) ){ // Angle axis is mirrored at 0
    1954           0 :     angleY = -angleY;
    1955           0 :   }
    1956           0 :   double var[5] = { static_cast<double>(Type), Z, static_cast<double>(QMax), Pad, angleY };
    1957           0 :   Long64_t bin = fWaveCorrectionMap->GetBin(var, kFALSE );
    1958           0 :   if( bin<0 ) return 0;
    1959           0 :   Double_t dY = fWaveCorrectionMap->GetBinContent(bin);
    1960           0 :   return (swapY ?-dY :dY);
    1961       99248 : }
    1962             : 

Generated by: LCOV version 1.11