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 : /// \class AliTPCExBEffective
17 : /// \brief Correct for the rest of ExB effect which are not covered by physical models
18 : ///
19 : /// Motivation:
20 : /// ExB correction:
21 : /// dr = c0* integral(Er/Ez) + c1* integral(Erphi/Ez)
22 : /// drphi = -c1* integral(Er/Ez) + c0* integral(Erphi/Ez)
23 : /// Where:
24 : /// wt = Bz*(k*vdrift/E) ~ 0.3 at B=0.5 T
25 : /// c0 = 1/(1+T2*T2*wt*wt)
26 : /// c1 = T1*wt/(1+T1*T1*wt*wt)
27 : ///
28 : /// Residual integral(Er/Ez,Erphi/Ez) obtained comparing the B field 0 and B field +-0.5 T setting
29 : /// minimizing track matching residuals
30 : /// delta(Er/Ez) ~ sum[ poln(r) * polm(z) * cos(n,phi)]
31 :
32 : #include "AliMagF.h"
33 : #include "TGeoGlobalMagField.h"
34 : #include "AliTPCcalibDB.h"
35 : #include "AliTPCParam.h"
36 : #include "AliLog.h"
37 :
38 : #include "TMath.h"
39 : #include "AliTPCROC.h"
40 : #include "AliTPCExBEffective.h"
41 : /// \cond CLASSIMP
42 24 : ClassImp(AliTPCExBEffective)
43 : /// \endcond
44 :
45 : AliTPCExBEffective::AliTPCExBEffective()
46 9 : : AliTPCCorrection("ExB_effective","ExB effective"),
47 9 : fC0(1.),fC1(0.),
48 9 : fPolynomA(0),
49 9 : fPolynomC(0),
50 9 : fPolynomValA(0),
51 9 : fPolynomValC(0)
52 45 : {
53 : //
54 : // default constructor
55 : //
56 18 : }
57 :
58 0 : AliTPCExBEffective::~AliTPCExBEffective() {
59 : /// default destructor
60 :
61 0 : }
62 :
63 :
64 :
65 : void AliTPCExBEffective::Init() {
66 : /// Initialization funtion
67 :
68 18 : AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
69 9 : if (!magF) AliError("Magneticd field - not initialized");
70 9 : Double_t bzField = magF->SolenoidField()/10.; //field in T
71 9 : AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
72 9 : if (!param) AliError("Parameters - not initialized");
73 9 : Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
74 : Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
75 9 : Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
76 : // Correction Terms for effective omegaTau; obtained by a laser calibration run
77 9 : SetOmegaTauT1T2(wt,fT1,fT2);
78 :
79 :
80 9 : }
81 :
82 : void AliTPCExBEffective::Update(const TTimeStamp &/*timeStamp*/) {
83 : /// Update function
84 :
85 0 : AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
86 0 : if (!magF) AliError("Magneticd field - not initialized");
87 0 : Double_t bzField = magF->SolenoidField()/10.; //field in T
88 0 : AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
89 0 : if (!param) AliError("Parameters - not initialized");
90 0 : Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
91 : Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
92 0 : Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
93 : // Correction Terms for effective omegaTau; obtained by a laser calibration run
94 0 : SetOmegaTauT1T2(wt,fT1,fT2);
95 :
96 :
97 0 : }
98 :
99 :
100 :
101 : void AliTPCExBEffective::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
102 : /// Calculates the correction due conical shape
103 :
104 0 : if (!fPolynomA) return;
105 0 : AliTPCROC * calROC = AliTPCROC::Instance();
106 0 : const Double_t kRTPC0 =calROC->GetPadRowRadii(0,0);
107 0 : const Double_t kRTPC1 =calROC->GetPadRowRadii(36,calROC->GetNRows(36)-1);
108 0 : Float_t rmiddle=(kRTPC0+kRTPC1)/2.;
109 : //
110 0 : Double_t phi = TMath::ATan2(x[1],x[0]);
111 0 : Double_t r = TMath::Sqrt(x[1]*x[1]+x[0]*x[0]);
112 0 : Double_t driftN = 1.-TMath::Abs(x[2])/calROC->GetZLength(0); // drift from 0 to 1
113 0 : Double_t localxN = 2*(r-rmiddle)/(kRTPC1-kRTPC0); // normalize local x position
114 : //
115 : Double_t erez = 0;
116 : Double_t erphiez = 0;
117 0 : if (roc%36<18) erez= GetSum(*fPolynomA, *fPolynomValA, localxN, driftN, phi,0);
118 0 : if (roc%36>=18) erez= GetSum(*fPolynomC, *fPolynomValC, localxN, driftN, phi,0);
119 0 : if (roc%36<18) erphiez= GetSum(*fPolynomA, *fPolynomValA, localxN, driftN, phi,1);
120 0 : if (roc%36>=18) erphiez= GetSum(*fPolynomC, *fPolynomValC, localxN, driftN, phi,1);
121 :
122 0 : Double_t dr = fC0 * erez + fC1 * erphiez;
123 0 : Double_t drphi = -fC1 * erez + fC0 * erphiez;
124 :
125 : // Calculate distorted position
126 0 : if ( r > 0.0 ) {
127 0 : r = r + dr;
128 0 : phi = phi + drphi/r;
129 0 : }
130 : // Calculate correction in cartesian coordinates
131 0 : dx[0] = r * TMath::Cos(phi) - x[0];
132 0 : dx[1] = r * TMath::Sin(phi) - x[1];
133 0 : dx[2] = 0.; // z distortion not implemented (1st order distortions)
134 :
135 0 : }
136 :
137 :
138 :
139 : Double_t AliTPCExBEffective::GetSum(const TMatrixD& mpol, const TMatrixD&mcoef, Double_t r, Double_t drift, Double_t phi, Int_t coord) const {
140 : /// Summation of the polynomials
141 :
142 0 : Int_t npols=mpol.GetNrows();
143 : Double_t sum=0;
144 0 : for (Int_t ipol=0;ipol<npols; ipol++){
145 : Double_t pR = 1, pD=1, pPhi=1;
146 0 : Int_t icoord = TMath::Nint(mpol(ipol,0));
147 0 : if (icoord!=coord) continue;
148 0 : Int_t npolR = TMath::Nint(mpol(ipol,1));
149 0 : Int_t npolD = TMath::Nint(mpol(ipol,2));
150 0 : Int_t npolPhi = TMath::Nint(mpol(ipol,3));
151 0 : Double_t coef=mcoef(ipol,0);
152 : //
153 0 : for (Int_t ipolR=1; ipolR<=npolR; ipolR++) pR*=r; // use simple polynoms
154 0 : for (Int_t ipolD=1; ipolD<=npolD; ipolD++) pD*=drift; // use simple polynoms
155 0 : pPhi=TMath::Cos(npolPhi*phi);
156 0 : sum+= pR*pD*pPhi*coef;
157 0 : }
158 0 : return sum;
159 : }
160 :
161 :
162 : void AliTPCExBEffective::SetPolynoms(const TMatrixD *polA,const TMatrixD *polC){
163 : /// Set correction polynom - coefficients
164 :
165 0 : fPolynomA = new TMatrixD(*polA);
166 0 : fPolynomC = new TMatrixD(*polC);
167 0 : }
168 :
169 : void AliTPCExBEffective::SetCoeficients(const TMatrixD *valA,const TMatrixD *valC){
170 : /// Set correction polynom - coefficients
171 :
172 0 : fPolynomValA = new TMatrixD(*valA);
173 0 : fPolynomValC = new TMatrixD(*valC);
174 0 : }
175 :
176 :
177 :
178 :
179 : void AliTPCExBEffective::Print(const Option_t* option) const {
180 : /// Print function to check the settings (e.g. the twist in the X direction)
181 : /// option=="a" prints the C0 and C1 coefficents for calibration purposes
182 :
183 0 : TString opt = option; opt.ToLower();
184 0 : printf("%s\t%s\n",GetName(),GetTitle());
185 :
186 0 : if (opt.Contains("a")) { // Print all details
187 0 : printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
188 0 : printf(" - C0: %1.4f, C1: %1.4f \n",fC0,fC1);
189 0 : fPolynomValA->Print();
190 0 : fPolynomValC->Print();
191 : }
192 :
193 :
194 0 : }
|