X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=TPC%2FAliTPCClusterParam.cxx;h=1e652b98877b23ca7cfd4968da86f19166347c4b;hb=32d22164b8b6d7ba91ba35a441c55232838dae02;hp=7c22eabdc47712472d084b7657be318b64d0dfc6;hpb=b17540e4dce729b11585d344e8ac03989856571b;p=u%2Fmrichter%2FAliRoot.git diff --git a/TPC/AliTPCClusterParam.cxx b/TPC/AliTPCClusterParam.cxx index 7c22eabdc47..1e652b98877 100644 --- a/TPC/AliTPCClusterParam.cxx +++ b/TPC/AliTPCClusterParam.cxx @@ -61,7 +61,7 @@ // // Example how to retrieve the paramterization: /* - AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT"); + AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT/OCDB"); AliCDBManager::Instance()->SetRun(0) AliTPCClusterParam * param = AliTPCcalibDB::Instance()->GetClusterParam(); @@ -91,9 +91,15 @@ AliTPCClusterParam::SetInstance(param); #include #include #include +#include #include #include #include +#include "AliTPCcalibDB.h" +#include "AliTPCParam.h" +#include "THnBase.h" + +#include "AliMathBase.h" ClassImp(AliTPCClusterParam) @@ -145,8 +151,15 @@ AliTPCClusterParam::AliTPCClusterParam(): TObject(), fRatio(0), fQNorm(0), + fQNormCorr(0), + fQNormHis(0), fQpadTnorm(0), // q pad normalization - Total charge - fQpadMnorm(0) // q pad normalization - Max charge + fQpadMnorm(0), // q pad normalization - Max charge + fWaveCorrectionMap(0), + fWaveCorrectionMirroredPad( kFALSE ), + fWaveCorrectionMirroredZ( kFALSE ), + fWaveCorrectionMirroredAngle( kFALSE ), + fResolutionYMap(0) // { // @@ -154,21 +167,31 @@ AliTPCClusterParam::AliTPCClusterParam(): // fPosQTnorm[0] = 0; fPosQTnorm[1] = 0; fPosQTnorm[2] = 0; fPosQMnorm[0] = 0; fPosQMnorm[1] = 0; fPosQMnorm[2] = 0; + // + fPosYcor[0] = 0; fPosYcor[1] = 0; fPosYcor[2] = 0; + fPosZcor[0] = 0; fPosZcor[1] = 0; fPosZcor[2] = 0; + fErrorRMSSys[0]=0; fErrorRMSSys[1]=0; } AliTPCClusterParam::AliTPCClusterParam(const AliTPCClusterParam& param): TObject(param), fRatio(0), fQNorm(0), + fQNormCorr(0), + fQNormHis(0), fQpadTnorm(new TVectorD(*(param.fQpadTnorm))), // q pad normalization - Total charge - fQpadMnorm(new TVectorD(*(param.fQpadMnorm))) // q pad normalization - Max charge - + fQpadMnorm(new TVectorD(*(param.fQpadMnorm))), // q pad normalization - Max charge + fWaveCorrectionMap(0), + fWaveCorrectionMirroredPad( kFALSE ), + fWaveCorrectionMirroredZ( kFALSE ), + fWaveCorrectionMirroredAngle( kFALSE ), + fResolutionYMap(0) { // // copy constructor // - memcpy(this, ¶m,sizeof(AliTPCClusterParam)); if (param.fQNorm) fQNorm = (TObjArray*) param.fQNorm->Clone(); + if (param.fQNormHis) fQNormHis = (TObjArray*) param.fQNormHis->Clone(); // if (param.fPosQTnorm[0]){ fPosQTnorm[0] = new TVectorD(*(param.fPosQTnorm[0])); @@ -179,6 +202,58 @@ AliTPCClusterParam::AliTPCClusterParam(const AliTPCClusterParam& param): fPosQMnorm[1] = new TVectorD(*(param.fPosQMnorm[1])); fPosQMnorm[2] = new TVectorD(*(param.fPosQMnorm[2])); } + if (param.fPosYcor[0]){ + fPosYcor[0] = new TVectorD(*(param.fPosYcor[0])); + fPosYcor[1] = new TVectorD(*(param.fPosYcor[1])); + fPosYcor[2] = new TVectorD(*(param.fPosYcor[2])); + // + fPosZcor[0] = new TVectorD(*(param.fPosZcor[0])); + fPosZcor[1] = new TVectorD(*(param.fPosZcor[1])); + fPosZcor[2] = new TVectorD(*(param.fPosZcor[2])); + } + + for (Int_t ii = 0; ii < 2; ++ii) { + for (Int_t jj = 0; jj < 3; ++jj) { + for (Int_t kk = 0; kk < 4; ++kk) { + fParamS0[ii][jj][kk] = param.fParamS0[ii][jj][kk]; + fErrorS0[ii][jj][kk] = param.fErrorS0[ii][jj][kk]; + fParamRMS0[ii][jj][kk] = param.fParamRMS0[ii][jj][kk]; + fErrorRMS0[ii][jj][kk] = param.fErrorRMS0[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 7; ++kk) { + fParamS0Par[ii][jj][kk] = param.fParamS0Par[ii][jj][kk]; + fErrorS0Par[ii][jj][kk] = param.fErrorS0Par[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 6; ++kk) { + fParamSQ[ii][jj][kk] = param.fParamSQ[ii][jj][kk]; + fErrorSQ[ii][jj][kk] = param.fErrorSQ[ii][jj][kk]; + fParamRMSQ[ii][jj][kk] = param.fParamRMSQ[ii][jj][kk]; + fErrorRMSQ[ii][jj][kk] = param.fErrorRMSQ[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 9; ++kk) { + fParamSQPar[ii][jj][kk] = param.fParamSQPar[ii][jj][kk]; + fErrorSQPar[ii][jj][kk] = param.fErrorSQPar[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 2; ++kk) { + fRMSSigmaFit[ii][jj][kk] = param.fRMSSigmaFit[ii][jj][kk]; + } + } + for (Int_t jj = 0; jj < 4; ++jj) { + fParamS1[ii][jj] = param.fParamS1[ii][jj]; + fErrorS1[ii][jj] = param.fErrorS1[ii][jj]; + } + for (Int_t jj = 0; jj < 5; ++jj) { + fParamRMS1[ii][jj] = param.fParamRMS1[ii][jj]; + fErrorRMS1[ii][jj] = param.fErrorRMS1[ii][jj]; + } + fErrorRMSSys[ii] = param.fErrorRMSSys[ii]; + for (Int_t jj = 0; jj < 2; ++jj){ + fRMSSigmaRatio[ii][jj] = param.fRMSSigmaRatio[ii][jj]; + } + } + + SetWaveCorrectionMap( param.fWaveCorrectionMap ); + SetResolutionYMap( param.fResolutionYMap ); } @@ -187,8 +262,8 @@ AliTPCClusterParam & AliTPCClusterParam::operator=(const AliTPCClusterParam& par // Assignment operator // if (this != ¶m) { - memcpy(this, ¶m,sizeof(AliTPCClusterParam)); if (param.fQNorm) fQNorm = (TObjArray*) param.fQNorm->Clone(); + if (param.fQNormHis) fQNormHis = (TObjArray*) param.fQNormHis->Clone(); if (param.fPosQTnorm[0]){ fPosQTnorm[0] = new TVectorD(*(param.fPosQTnorm[0])); fPosQTnorm[1] = new TVectorD(*(param.fPosQTnorm[1])); @@ -198,6 +273,58 @@ AliTPCClusterParam & AliTPCClusterParam::operator=(const AliTPCClusterParam& par fPosQMnorm[1] = new TVectorD(*(param.fPosQMnorm[1])); fPosQMnorm[2] = new TVectorD(*(param.fPosQMnorm[2])); } + if (param.fPosYcor[0]){ + fPosYcor[0] = new TVectorD(*(param.fPosYcor[0])); + fPosYcor[1] = new TVectorD(*(param.fPosYcor[1])); + fPosYcor[2] = new TVectorD(*(param.fPosYcor[2])); + // + fPosZcor[0] = new TVectorD(*(param.fPosZcor[0])); + fPosZcor[1] = new TVectorD(*(param.fPosZcor[1])); + fPosZcor[2] = new TVectorD(*(param.fPosZcor[2])); + } + + for (Int_t ii = 0; ii < 2; ++ii) { + for (Int_t jj = 0; jj < 3; ++jj) { + for (Int_t kk = 0; kk < 4; ++kk) { + fParamS0[ii][jj][kk] = param.fParamS0[ii][jj][kk]; + fErrorS0[ii][jj][kk] = param.fErrorS0[ii][jj][kk]; + fParamRMS0[ii][jj][kk] = param.fParamRMS0[ii][jj][kk]; + fErrorRMS0[ii][jj][kk] = param.fErrorRMS0[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 7; ++kk) { + fParamS0Par[ii][jj][kk] = param.fParamS0Par[ii][jj][kk]; + fErrorS0Par[ii][jj][kk] = param.fErrorS0Par[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 6; ++kk) { + fParamSQ[ii][jj][kk] = param.fParamSQ[ii][jj][kk]; + fErrorSQ[ii][jj][kk] = param.fErrorSQ[ii][jj][kk]; + fParamRMSQ[ii][jj][kk] = param.fParamRMSQ[ii][jj][kk]; + fErrorRMSQ[ii][jj][kk] = param.fErrorRMSQ[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 9; ++kk) { + fParamSQPar[ii][jj][kk] = param.fParamSQPar[ii][jj][kk]; + fErrorSQPar[ii][jj][kk] = param.fErrorSQPar[ii][jj][kk]; + } + for (Int_t kk = 0; kk < 2; ++kk) { + fRMSSigmaFit[ii][jj][kk] = param.fRMSSigmaFit[ii][jj][kk]; + } + } + for (Int_t jj = 0; jj < 4; ++jj) { + fParamS1[ii][jj] = param.fParamS1[ii][jj]; + fErrorS1[ii][jj] = param.fErrorS1[ii][jj]; + } + for (Int_t jj = 0; jj < 5; ++jj) { + fParamRMS1[ii][jj] = param.fParamRMS1[ii][jj]; + fErrorRMS1[ii][jj] = param.fErrorRMS1[ii][jj]; + } + fErrorRMSSys[ii] = param.fErrorRMSSys[ii]; + for (Int_t jj = 0; jj < 2; ++jj){ + fRMSSigmaRatio[ii][jj] = param.fRMSSigmaRatio[ii][jj]; + } + } + + SetWaveCorrectionMap( param.fWaveCorrectionMap ); + SetResolutionYMap( param.fResolutionYMap ); } return *this; } @@ -208,7 +335,10 @@ AliTPCClusterParam::~AliTPCClusterParam(){ // destructor // if (fQNorm) fQNorm->Delete(); + if (fQNormCorr) delete fQNormCorr; + if (fQNormHis) fQNormHis->Delete(); delete fQNorm; + delete fQNormHis; if (fPosQTnorm[0]){ delete fPosQTnorm[0]; delete fPosQTnorm[1]; @@ -218,6 +348,17 @@ AliTPCClusterParam::~AliTPCClusterParam(){ delete fPosQMnorm[1]; delete fPosQMnorm[2]; } + if (fPosYcor[0]){ + delete fPosYcor[0]; + delete fPosYcor[1]; + delete fPosYcor[2]; + // + delete fPosZcor[0]; + delete fPosZcor[1]; + delete fPosZcor[2]; + } + delete fWaveCorrectionMap; + delete fResolutionYMap; } @@ -226,24 +367,24 @@ void AliTPCClusterParam::FitResol0(TTree * tree, Int_t dim, Int_t type, Float_t // Fit z - angular dependence of resolution // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"Resol:AngleM:Zm"); - char varErr[100]; - sprintf(varErr,"Sigma:AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean<0",dim,type); - // - Int_t entries = tree->Draw(varVal,varCut); + TString varVal; + varVal="Resol:AngleM:Zm"; + TString varErr; + varErr="Sigma:AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type); + // + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[10000], py[10000], pz[10000]; Float_t ex[10000], ey[10000], ez[10000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -279,24 +420,24 @@ void AliTPCClusterParam::FitResol0Par(TTree * tree, Int_t dim, Int_t type, Float // Fit z - angular dependence of resolution // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"Resol:AngleM:Zm"); - char varErr[100]; - sprintf(varErr,"Sigma:AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean<0",dim,type); - // - Int_t entries = tree->Draw(varVal,varCut); + TString varVal; + varVal="Resol:AngleM:Zm"; + TString varErr; + varErr="Sigma:AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type); + // + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[10000], py[10000], pz[10000]; Float_t ex[10000], ey[10000], ez[10000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -344,24 +485,24 @@ void AliTPCClusterParam::FitResol1(TTree * tree, Int_t dim, Float_t *param0, Flo // Fit z - angular dependence of resolution - pad length scaling // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"Resol:AngleM*sqrt(Length):Zm/Length"); - char varErr[100]; - sprintf(varErr,"Sigma:AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&QMean<0",dim); - // - Int_t entries = tree->Draw(varVal,varCut); + TString varVal; + varVal="Resol:AngleM*sqrt(Length):Zm/Length"; + TString varErr; + varErr="Sigma:AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&QMean<0",dim); + // + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[10000], py[10000], pz[10000]; Float_t ex[10000], ey[10000], ez[10000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -396,27 +537,27 @@ void AliTPCClusterParam::FitResolQ(TTree * tree, Int_t dim, Int_t type, Float_t // Fit z - angular dependence of resolution - Q scaling // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"Resol:AngleM/sqrt(QMean):Zm/QMean"); + TString varVal; + varVal="Resol:AngleM/sqrt(QMean):Zm/QMean"; char varVal0[100]; - sprintf(varVal0,"Resol:AngleM:Zm"); + snprintf(varVal0,100,"Resol:AngleM:Zm"); // - char varErr[100]; - sprintf(varErr,"Sigma:AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean>0",dim,type); + TString varErr; + varErr="Sigma:AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type); // - Int_t entries = tree->Draw(varVal,varCut); + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000]; Float_t ex[20000], ey[20000], ez[20000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -463,27 +604,27 @@ void AliTPCClusterParam::FitResolQPar(TTree * tree, Int_t dim, Int_t type, Float // Fit z - angular dependence of resolution - Q scaling - parabolic correction // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"Resol:AngleM/sqrt(QMean):Zm/QMean"); + TString varVal; + varVal="Resol:AngleM/sqrt(QMean):Zm/QMean"; char varVal0[100]; - sprintf(varVal0,"Resol:AngleM:Zm"); + snprintf(varVal0,100,"Resol:AngleM:Zm"); // - char varErr[100]; - sprintf(varErr,"Sigma:AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean>0",dim,type); + TString varErr; + varErr="Sigma:AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type); // - Int_t entries = tree->Draw(varVal,varCut); + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000]; Float_t ex[20000], ey[20000], ez[20000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -543,24 +684,24 @@ void AliTPCClusterParam::FitRMS0(TTree * tree, Int_t dim, Int_t type, Float_t *p // Fit z - angular dependence of resolution // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"RMSm:AngleM:Zm"); - char varErr[100]; - sprintf(varErr,"sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean<0",dim,type); - // - Int_t entries = tree->Draw(varVal,varCut); + TString varVal; + varVal="RMSm:AngleM:Zm"; + TString varErr; + varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type); + // + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[10000], py[10000], pz[10000]; Float_t ex[10000], ey[10000], ez[10000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -595,24 +736,24 @@ void AliTPCClusterParam::FitRMS1(TTree * tree, Int_t dim, Float_t *param0, Float // Fit z - angular dependence of resolution - pad length scaling // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"RMSm:AngleM*Length:Zm"); - char varErr[100]; - sprintf(varErr,"sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Pad"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&QMean<0",dim); - // - Int_t entries = tree->Draw(varVal,varCut); + TString varVal; + varVal="RMSm:AngleM*Length:Zm"; + TString varErr; + varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Pad"; + TString varCut; + varCut=Form("Dim==%d&&QMean<0",dim); + // + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[10000], py[10000], pz[10000]; Float_t type[10000], ey[10000], ez[10000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint] = tree->GetV2()[ipoint]; ez[ipoint] = tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -650,27 +791,27 @@ void AliTPCClusterParam::FitRMSQ(TTree * tree, Int_t dim, Int_t type, Float_t *p // Fit z - angular dependence of resolution - Q scaling // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"RMSm:AngleM/sqrt(QMean):Zm/QMean"); + TString varVal; + varVal="RMSm:AngleM/sqrt(QMean):Zm/QMean"; char varVal0[100]; - sprintf(varVal0,"RMSm:AngleM:Zm"); + snprintf(varVal0,100,"RMSm:AngleM:Zm"); // - char varErr[100]; - sprintf(varErr,"sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs"); - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean>0",dim,type); + TString varErr; + varErr="sqrt((1./(100.*sqrt(12.))^2)+RMSe0^2):AngleS:Zs"; + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean>0",dim,type); // - Int_t entries = tree->Draw(varVal,varCut); + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[20000], py[20000], pz[20000], pu[20000], pt[20000]; Float_t ex[20000], ey[20000], ez[20000]; // - tree->Draw(varErr,varCut); + tree->Draw(varErr.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; ey[ipoint]= tree->GetV2()[ipoint]; ez[ipoint]= tree->GetV1()[ipoint]; } - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV3()[ipoint]; py[ipoint]= tree->GetV2()[ipoint]; @@ -718,16 +859,16 @@ void AliTPCClusterParam::FitRMSSigma(TTree * tree, Int_t dim, Int_t type, Float_ // Fit z - angular dependence of resolution - Q scaling // // Int_t dim=0, type=0; - char varVal[100]; - sprintf(varVal,"RMSs:RMSm"); + TString varVal; + varVal="RMSs:RMSm"; // - char varCut[100]; - sprintf(varCut,"Dim==%d&&Pad==%d&&QMean<0",dim,type); + TString varCut; + varCut=Form("Dim==%d&&Pad==%d&&QMean<0",dim,type); // - Int_t entries = tree->Draw(varVal,varCut); + Int_t entries = tree->Draw(varVal.Data(),varCut); Float_t px[20000], py[20000]; // - tree->Draw(varVal,varCut); + tree->Draw(varVal.Data(),varCut); for (Int_t ipoint=0; ipointGetV2()[ipoint]; py[ipoint]= tree->GetV1()[ipoint]; @@ -747,7 +888,7 @@ void AliTPCClusterParam::FitRMSSigma(TTree * tree, Int_t dim, Int_t type, Float_ -Float_t AliTPCClusterParam::GetError0(Int_t dim, Int_t type, Float_t z, Float_t angle){ +Float_t AliTPCClusterParam::GetError0(Int_t dim, Int_t type, Float_t z, Float_t angle) const { // // // @@ -760,7 +901,7 @@ Float_t AliTPCClusterParam::GetError0(Int_t dim, Int_t type, Float_t z, Float_t } -Float_t AliTPCClusterParam::GetError0Par(Int_t dim, Int_t type, Float_t z, Float_t angle){ +Float_t AliTPCClusterParam::GetError0Par(Int_t dim, Int_t type, Float_t z, Float_t angle) const { // // // @@ -777,7 +918,7 @@ Float_t AliTPCClusterParam::GetError0Par(Int_t dim, Int_t type, Float_t z, Floa -Float_t AliTPCClusterParam::GetError1(Int_t dim, Int_t type, Float_t z, Float_t angle){ +Float_t AliTPCClusterParam::GetError1(Int_t dim, Int_t type, Float_t z, Float_t angle) const { // // // @@ -792,7 +933,7 @@ Float_t AliTPCClusterParam::GetError1(Int_t dim, Int_t type, Float_t z, Float_t return value; } -Float_t AliTPCClusterParam::GetErrorQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean){ +Float_t AliTPCClusterParam::GetErrorQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const { // // // @@ -808,7 +949,7 @@ Float_t AliTPCClusterParam::GetErrorQ(Int_t dim, Int_t type, Float_t z, Float_t } -Float_t AliTPCClusterParam::GetErrorQPar(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean){ +Float_t AliTPCClusterParam::GetErrorQPar(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const { // // // @@ -827,7 +968,7 @@ Float_t AliTPCClusterParam::GetErrorQPar(Int_t dim, Int_t type, Float_t z, Floa } -Float_t AliTPCClusterParam::GetErrorQParScaled(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean){ +Float_t AliTPCClusterParam::GetErrorQParScaled(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const { // // // @@ -848,7 +989,7 @@ Float_t AliTPCClusterParam::GetErrorQParScaled(Int_t dim, Int_t type, Float_t z } -Float_t AliTPCClusterParam::GetRMS0(Int_t dim, Int_t type, Float_t z, Float_t angle){ +Float_t AliTPCClusterParam::GetRMS0(Int_t dim, Int_t type, Float_t z, Float_t angle) const { // // calculate mean RMS of cluster - z,angle - parameters for each pad and dimension separatelly // @@ -860,7 +1001,7 @@ Float_t AliTPCClusterParam::GetRMS0(Int_t dim, Int_t type, Float_t z, Float_t a return value; } -Float_t AliTPCClusterParam::GetRMS1(Int_t dim, Int_t type, Float_t z, Float_t angle){ +Float_t AliTPCClusterParam::GetRMS1(Int_t dim, Int_t type, Float_t z, Float_t angle) const { // // calculate mean RMS of cluster - z,angle - pad length scalling // @@ -879,7 +1020,7 @@ Float_t AliTPCClusterParam::GetRMS1(Int_t dim, Int_t type, Float_t z, Float_t a return value; } -Float_t AliTPCClusterParam::GetRMSQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean){ +Float_t AliTPCClusterParam::GetRMSQ(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const { // // calculate mean RMS of cluster - z,angle, Q dependence // @@ -893,7 +1034,7 @@ Float_t AliTPCClusterParam::GetRMSQ(Int_t dim, Int_t type, Float_t z, Float_t a return value; } -Float_t AliTPCClusterParam::GetRMSSigma(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean){ +Float_t AliTPCClusterParam::GetRMSSigma(Int_t dim, Int_t type, Float_t z, Float_t angle, Float_t Qmean) const { // // calculates RMS of signal shape fluctuation // @@ -903,7 +1044,7 @@ Float_t AliTPCClusterParam::GetRMSSigma(Int_t dim, Int_t type, Float_t z, Float return value; } -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){ +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 { // // calculates vallue - sigma distortion contribution // @@ -1110,19 +1251,19 @@ void AliTPCClusterParam::Test(TTree * tree, const char *output){ char hcut1[300]; char hexp1[300]; // - sprintf(hname1,"Delta0 Dir %d Pad %d",idim,ipad); - sprintf(hcut1,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); - sprintf(hexp1,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1); + snprintf(hname1,300,"Delta0 Dir %d Pad %d",idim,ipad); + snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); + snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1); TH1F his1DRel0(hname1, hname1, 100,-0.2, 0.2); - sprintf(hname1,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); + snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); tree->Draw(hexp1,hcut1,""); his1DRel0.Write(); // - sprintf(hname1,"Delta0Par Dir %d Pad %d",idim,ipad); - sprintf(hcut1,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); - sprintf(hexp1,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1); + snprintf(hname1,300,"Delta0Par Dir %d Pad %d",idim,ipad); + snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); + snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol>>%s",hname1); TH1F his1DRel0Par(hname1, hname1, 100,-0.2, 0.2); - sprintf(hname1,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); + snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); tree->Draw(hexp1,hcut1,""); his1DRel0Par.Write(); // @@ -1137,19 +1278,19 @@ void AliTPCClusterParam::Test(TTree * tree, const char *output){ char hcut1[300]; char hexp1[300]; // - sprintf(hname1,"2DDelta0 Dir %d Pad %d",idim,ipad); - sprintf(hcut1,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); - sprintf(hexp1,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1); + snprintf(hname1,300,"2DDelta0 Dir %d Pad %d",idim,ipad); + snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); + snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1); TProfile2D profDRel0(hname1, hname1, 6,0,250,6,0,1); - sprintf(hname1,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); + snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); tree->Draw(hexp1,hcut1,""); profDRel0.Write(); // - sprintf(hname1,"2DDelta0Par Dir %d Pad %d",idim,ipad); - sprintf(hcut1,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); - sprintf(hexp1,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1); + snprintf(hname1,300,"2DDelta0Par Dir %d Pad %d",idim,ipad); + snprintf(hcut1,300,"Dim==%d&&QMean<0&&Pad==%d",idim,ipad); + snprintf(hexp1,300,"(Resol-AliTPCClusterParam::SGetError0Par(Dim,Pad,Zm,AngleM))/Resol:AngleM:Zm>>%s",hname1); TProfile2D profDRel0Par(hname1, hname1,6,0,250,6,0,1); - sprintf(hname1,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); + snprintf(hname1,300,"Dim==%d&&QMean<0&&Pad=%d",idim,ipad); tree->Draw(hexp1,hcut1,""); profDRel0Par.Write(); // @@ -1285,7 +1426,7 @@ Float_t AliTPCClusterParam::Qnorm(Int_t ipad, Int_t itype, Float_t dr, Float_t t // type - 0 Qtot 1 Qmax // ipad - 0 (0.75 cm) ,1 (1 cm), 2 (1.5 cm) // - //expession formula - TString *strq0 = toolkit.FitPlane(chain,"dedxQ.fElements[2]","dr++ty++tz++dr*ty++dr*tz++ty*tz++ty^2++tz^2","IPad==0",chi2,npoints,param,covar,0,100000); + //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); if (fQNorm==0) return 0; TVectorD * norm = (TVectorD*)fQNorm->At(3*itype+ipad); @@ -1308,7 +1449,34 @@ Float_t AliTPCClusterParam::Qnorm(Int_t ipad, Int_t itype, Float_t dr, Float_t t -void AliTPCClusterParam::SetQnorm(Int_t ipad, Int_t itype, TVectorD * norm){ +Float_t AliTPCClusterParam::QnormHis(Int_t ipad, Int_t itype, Float_t dr, Float_t p2, Float_t p3){ + // get Q normalization + // type - 0 Qtot 1 Qmax + // ipad - 0 (0.75 cm) ,1 (1 cm), 2 (1.5 cm) + // + + if (fQNormHis==0) return 0; + TH3F * norm = (TH3F*)fQNormHis->At(4*itype+ipad); + if (!norm) return 1; + p2=TMath::Abs(p2); + dr=TMath::Min(dr,Float_t(norm->GetXaxis()->GetXmax()-norm->GetXaxis()->GetBinWidth(0))); + dr=TMath::Max(dr,Float_t(norm->GetXaxis()->GetXmin()+norm->GetXaxis()->GetBinWidth(0))); + // + p2=TMath::Min(p2,Float_t(norm->GetYaxis()->GetXmax()-norm->GetYaxis()->GetBinWidth(0))); + p2=TMath::Max(p2,Float_t(norm->GetYaxis()->GetXmin()+norm->GetYaxis()->GetBinWidth(0))); + // + p3=TMath::Min(p3,Float_t(norm->GetZaxis()->GetXmax()-norm->GetZaxis()->GetBinWidth(0))); + p3=TMath::Max(p3,Float_t(norm->GetZaxis()->GetXmin()+norm->GetZaxis()->GetBinWidth(0))); + // + Double_t res = norm->GetBinContent(norm->FindBin(dr,p2,p3)); + if (res==0) res = norm->GetBinContent(norm->FindBin(0.5,0.5,0.5)); // This is just hack - to be fixed entries without + + return res; +} + + + +void AliTPCClusterParam::SetQnorm(Int_t ipad, Int_t itype, const TVectorD *const norm){ // // set normalization // @@ -1320,6 +1488,50 @@ void AliTPCClusterParam::SetQnorm(Int_t ipad, Int_t itype, TVectorD * norm){ fQNorm->AddAt(new TVectorD(*norm), itype*3+ipad); } +void AliTPCClusterParam::ResetQnormCorr(){ + // + // + // + if (!fQNormCorr) fQNormCorr= new TMatrixD(12,6); + for (Int_t irow=0;irow<12; irow++) + for (Int_t icol=0;icol<6; icol++){ + (*fQNormCorr)(irow,icol)=1.; // default - no correction + if (irow>5) (*fQNormCorr)(irow,icol)=0.; // default - no correction + } +} + +void AliTPCClusterParam::SetQnormCorr(Int_t ipad, Int_t itype, Int_t corrType, Float_t val){ + // + // ipad - pad type + // itype - 0- qtot 1-qmax + // corrType - 0 - s0y corr - eff. PRF corr + // - 1 - s0z corr - eff. TRF corr + // - 2 - d0y - eff. diffusion correction y + // - 3 - d0z - eff. diffusion correction + // - 4 - eff length - eff.length - wire pitch + x diffsion + // - 5 - pad type normalization + if (!fQNormCorr) { + ResetQnormCorr(); + } + // + // eff shap parameterization matrix + // + // rows + // itype*3+ipad - itype=0 qtot itype=1 qmax ipad=0 + // + if (itype<2) (*fQNormCorr)(itype*3+ipad, corrType) *= val; // multiplicative correction + if (itype>=2) (*fQNormCorr)(itype*3+ipad, corrType)+= val; // additive correction +} + +Double_t AliTPCClusterParam::GetQnormCorr(Int_t ipad, Int_t itype, Int_t corrType) const{ + // + // see AliTPCClusterParam::SetQnormCorr + // + if (!fQNormCorr) return 0; + return (*fQNormCorr)(itype*3+ipad, corrType); +} + + 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){ // // Make Q normalization as function of following parameters @@ -1398,6 +1610,9 @@ Float_t AliTPCClusterParam::QnormPos(Int_t ipad,Bool_t isMax, Float_t pad, Float result+=dt*dt*(dq1)*param[index++]; //26 result+=dt*dt*dt*(dq1)*param[index++]; //27 + if (result<0.75) result=0.75; + if (result>1.25) result=1.25; + return result; } @@ -1406,3 +1621,341 @@ Float_t AliTPCClusterParam::QnormPos(Int_t ipad,Bool_t isMax, Float_t pad, Float +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*/){ + + // + // Make postion correction + // type - 0 - y correction + // 1 - z correction + // ipad - 0, 1, 2 - short, medium long pads + // pad - float pad number + // time - float time bin number + // z - z of the cluster + + // + //chainres->SetAlias("dp","(-1+(Cl.fZ>0)*2)*((Cl.fPad-int(Cl.fPad))-0.5)"); + //chainres->SetAlias("dt","(-1+(Cl.fZ>0)*2)*((Cl.fTimeBin-0.66-int(Cl.fTimeBin-0.66))-0.5)"); + //chainres->SetAlias("sp","(sin(dp*pi)-dp*pi)"); + //chainres->SetAlias("st","(sin(dt)-dt)"); + // + //chainres->SetAlias("di","sqrt(1.-abs(Cl.fZ/250.))"); + + // + // Derived variables + // + Double_t dp = (-1+(z>0)*2)*((pad-int(pad))-0.5); + Double_t dt = (-1+(z>0)*2)*((time-0.66-int(time-0.66))-0.5); + Double_t sp = (TMath::Sin(dp*TMath::Pi())-dp*TMath::Pi()); + Double_t st = (TMath::Sin(dt)-dt); + // + Double_t di = TMath::Sqrt(TMath::Abs(1.-TMath::Abs(z/250.))); + // + // + // + TVectorD * pvec = 0; + if (type==0){ + pvec = fPosYcor[ipad]; + }else{ + pvec = fPosZcor[ipad]; + } + TVectorD ¶m = *pvec; + // + Double_t result=0; + Int_t index =1; + + if (type==0){ + // y corr + result+=(dp)*param[index++]; //1 + result+=(dp)*di*param[index++]; //2 + // + result+=(sp)*param[index++]; //3 + result+=(sp)*di*param[index++]; //4 + } + if (type==1){ + result+=(dt)*param[index++]; //1 + result+=(dt)*di*param[index++]; //2 + // + result+=(st)*param[index++]; //3 + result+=(st)*di*param[index++]; //4 + } + if (TMath::Abs(result)>0.05) return 0; + return result; +} + + + +Double_t AliTPCClusterParam::GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1){ + // + // 2 D gaus convoluted with angular effect + // See in mathematica: + //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}]] + // + //TF1 f1("f1","AliTPCClusterParam::GaussConvolution(x,0,1,0,0.1,0.1)",-2,2) + //TF2 f2("f2","AliTPCClusterParam::GaussConvolution(x,y,1,1,0.1,0.1)",-2,2,-2,2) + // + const Double_t kEpsilon = 0.0001; + const Double_t twoPi = TMath::TwoPi(); + const Double_t hnorm = 0.5/TMath::Sqrt(twoPi); + const Double_t sqtwo = TMath::Sqrt(2.); + + if ((TMath::Abs(k0)+TMath::Abs(k1))GetParameters(); + Double_t padLength= param->GetPadPitchLength(sector,row); + Double_t padWidth = param->GetPadPitchWidth(sector); + Double_t zwidth = param->GetZWidth(); + Double_t effLength= padLength+(param->GetWWPitch(0)+TMath::Sqrt(ctime*zwidth)*param->GetDiffT())*effPad; + + // diffusion in pad, time bin units + Double_t diffT=TMath::Sqrt(ctime*zwidth)*param->GetDiffT()/padWidth; + Double_t diffL=TMath::Sqrt(ctime*zwidth)*param->GetDiffL()/zwidth; + diffT*=effDiff; // + diffL*=effDiff; // + // + // transform angular effect to pad units + // + Double_t pky = ky*effLength/padWidth; + Double_t pkz = kz*effLength/zwidth; + // position in pad unit + Double_t py = (cpad+0.5)-TMath::Nint(cpad+0.5); + Double_t pz = (ctime+0.5)-TMath::Nint(ctime+0.5); + // + // + Double_t sy = TMath::Sqrt(rmsy0*rmsy0+diffT*diffT); + Double_t sz = TMath::Sqrt(rmsz0*rmsz0+diffL*diffL); + //return GaussConvolutionGamma4(py,pz, pky,pkz,sy,sz,tau); + Double_t length = padLength*TMath::Sqrt(1+ky*ky+kz*kz); + return GaussConvolution(py,pz, pky,pkz,sy,sz)*length; +} + +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){ + // + // + // cpad - pad (y) coordinate + // ctime - time(z) coordinate + // ky - dy/dx + // kz - dz/dx + // rmsy0 - RF width in pad units + // rmsz0 - RF width in time bin units + // qtot - the sum of signal in cluster - without thr correction + // thr - threshold + // effLength - contibution of PRF and diffusion + // effDiff - overwrite diffusion + + // Response function aproximated by convolution of gaussian with angular effect (integral=1) + // + // Gaus width sy and sz is determined by RF width and diffusion + // Integral of Q is equal 1 + // Q max is calculated at position cpad, ctime + // + // + // + AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters(); + Double_t padLength= param->GetPadPitchLength(sector,row); + Double_t padWidth = param->GetPadPitchWidth(sector); + Double_t zwidth = param->GetZWidth(); + Double_t effLength= padLength+(param->GetWWPitch(0)+TMath::Sqrt(ctime*zwidth)*param->GetDiffT())*effPad; + // + // diffusion in pad units + Double_t diffT=TMath::Sqrt(ctime*zwidth)*param->GetDiffT()/padWidth; + Double_t diffL=TMath::Sqrt(ctime*zwidth)*param->GetDiffL()/zwidth; + diffT*=effDiff; // + diffL*=effDiff; // + // + // transform angular effect to pad units + Double_t pky = ky*effLength/padWidth; + Double_t pkz = kz*effLength/zwidth; + // position in pad unit + // + Double_t py = (cpad+0.5)-TMath::Nint(cpad+0.5); + Double_t pz = (ctime+0.5)-TMath::Nint(ctime+0.5); + // + Double_t sy = TMath::Sqrt(rmsy0*rmsy0+diffT*diffT); + Double_t sz = TMath::Sqrt(rmsz0*rmsz0+diffL*diffL); + // + // + // + Double_t sumAll=0,sumThr=0; + // + Double_t corr =1; + Double_t qnorm=qtot; + for (Float_t iy=-3;iy<=3;iy+=1.) + for (Float_t iz=-4;iz<=4;iz+=1.){ + // Double_t val = GaussConvolutionGamma4(py-iy,pz-iz, pky,pkz, sy,sz,tau); + Double_t val = GaussConvolution(py-iy,pz-iz, pky,pkz, sy,sz); + Double_t qlocal =qnorm*val; + if (TMath::Abs(iy)<1.5&&TMath::Abs(iz)<1.5){ + sumThr+=qlocal; // Virtual charge used in cluster finder + } + else{ + if (qlocal>thr && TMath::Abs(iz)<2.5&&TMath::Abs(iy)<2.5) sumThr+=qlocal; + } + sumAll+=qlocal; + } + if (sumAll>0&&sumThr>0) { + corr=(sumThr)/sumAll; + } + // + Double_t length = padLength*TMath::Sqrt(1+ky*ky+kz*kz); + return corr*length; +} + + + +void AliTPCClusterParam::SetWaveCorrectionMap( THnBase *Map) +{ + // + // Set Correction Map for Y + // + delete fWaveCorrectionMap; + fWaveCorrectionMap = 0; + fWaveCorrectionMirroredPad = kFALSE; + fWaveCorrectionMirroredZ = kFALSE; + fWaveCorrectionMirroredAngle = kFALSE; + if( Map ){ + fWaveCorrectionMap = dynamic_cast( Map->Clone(Map->GetName())); + if( fWaveCorrectionMap ){ + fWaveCorrectionMirroredPad = ( fWaveCorrectionMap->GetAxis(3)->FindFixBin(0.5)<=1 ); // Pad axis is mirrored at 0.5 + fWaveCorrectionMirroredZ = ( fWaveCorrectionMap->GetAxis(1)->FindFixBin(0)<=1); // Z axis is mirrored at 0 + fWaveCorrectionMirroredAngle = ( fWaveCorrectionMap->GetAxis(4)->FindFixBin(0.0)<=1 ); // Angle axis is mirrored at 0 + } + } +} + +void AliTPCClusterParam::SetResolutionYMap( THnBase *Map) +{ + // + // Set Resolution Map for Y + // + delete fResolutionYMap; + fResolutionYMap = 0; + if( Map ){ + fResolutionYMap = dynamic_cast( Map->Clone(Map->GetName())); + } +} + +Float_t AliTPCClusterParam::GetWaveCorrection(Int_t Type, Float_t Z, Int_t QMax, Float_t Pad, Float_t angleY ) const +{ + // + // Correct Y cluster coordinate using a map + // + + if( !fWaveCorrectionMap ) return 0; + Bool_t swapY = kFALSE; + Pad = Pad-(Int_t)Pad; + + if( TMath::Abs(Pad-0.5)<1.e-8 ){// one pad clusters a stored in underflow bins + Pad = -1.; + } else { + if( fWaveCorrectionMirroredPad && (Pad<0.5) ){ // cog axis is mirrored at 0.5 + swapY = !swapY; + Pad = 1.0 - Pad; + } + } + + if( fWaveCorrectionMirroredZ && (Z<0) ){ // Z axis is mirrored at 0 + swapY = !swapY; + Z = -Z; + } + + if( fWaveCorrectionMirroredAngle && (angleY<0) ){ // Angle axis is mirrored at 0 + angleY = -angleY; + } + double var[5] = { Type, Z, QMax, Pad, angleY }; + Long64_t bin = fWaveCorrectionMap->GetBin(var, kFALSE ); + if( bin<0 ) return 0; + Double_t dY = fWaveCorrectionMap->GetBinContent(bin); + return (swapY ?-dY :dY); +} +