o Add option for residual distortion
[u/mrichter/AliRoot.git] / TPC / Base / AliTPCComposedCorrection.cxx
CommitLineData
0116859c 1
2/**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17////////////////////////////////////////////////////////////////////////////////
18// //
19// AliTPCComposedCorrection class //
20// //
21// This class is creating a correction that is composed out of smaller //
22// corrections. //
23// There are two ways the sub-corrections can be combined into this one: //
24// 1. kParallel: All corrections are applied at the given position x and //
25// the dx terms are summed up (this commutes). //
26// 2. kQueue: The corrections are called in order. The first one at the //
27// given position x resulting in dx1, the second one is called at //
28// the corrected position (x+dx1) resulting in dx2, the third one //
29// is then called at position (x+dx1+dx2) and so forth. dx=dx1+dx2+... //
30// is returned. //
0f236b4e 31// 3. kQueueResidual: like kQueue with the exception that in case of //
32// a positive weight the 'Distortion' is called and in case of a negative //
33// weight the 'Correction' is called, where the absolute of the weight //
34// will be applied to the correction
0116859c 35// For the inverse of the correction this is taken into account by reversing //
36// the order the corrections are applied in the kQueue case (no issue for //
37// kParallel). //
38// //
39// date: 27/04/2010 //
40// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
41// //
42// Example usage: //
43// //
44// AliMagF mag("mag","mag"); //
45// AliTPCExBBShape exb; // B field shape distortions //
46// exb.SetBField(&mag); //
47// //
48// AliTPCExBTwist twist; // ExB Twist distortions //
49// twist.SetXTwist(0.001); //
50// //
51// TObjArray cs; cs.Add(&exb); cs.Add(&twist); //
52// //
53// AliTPCComposedCorrection cc; //
54// cc.SetCorrections(&cs); //
55// cc.SetOmegaTauT1T2(wt,T1,T2); //
56// cc.Print("DA"); //
57// cc.CreateHistoDRPhiinZR(0,100,100)->Draw("surf2"); //
58////////////////////////////////////////////////////////////////////////////////
59
60
61#include <TCollection.h>
e527a1b9 62#include <TTimeStamp.h>
b1f0a2a5 63#include <TIterator.h>
0f236b4e 64#include <TMath.h>
c9cbd2f2 65#include "AliLog.h"
0116859c 66
67#include "AliTPCComposedCorrection.h"
68
69
70AliTPCComposedCorrection::AliTPCComposedCorrection()
71 : AliTPCCorrection("composed_correction",
72 "composition of corrections"),
73 fCorrections(0),
cfe2c39a 74 fMode(kParallel),
75 fWeights(0) // weights of corrections
0116859c 76{
77 //
78 // default constructor
79 //
80}
81
82AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections,
83 AliTPCComposedCorrection::CompositionType mode)
84 : AliTPCCorrection("composed_correction",
85 "composition of corrections"),
86 fCorrections(corrections),
cfe2c39a 87 fMode(mode),
88 fWeights(0) //weights of correction
0116859c 89{
90 //
91 // Constructor that defines the set of corrections, this one is composed of.
92 //
93}
94
95AliTPCComposedCorrection::~AliTPCComposedCorrection() {
96 //
c9cbd2f2 97 // destructor
0116859c 98 //
c9cbd2f2 99 if (!fCorrections) {
100 AliInfo("No Correction-models were set: can not delete them");
101 } else {
102 TIterator *i=fCorrections->MakeIterator();
103 AliTPCCorrection *c;
104 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
105 delete c;
106 }
107 delete i;
108 }
cfe2c39a 109 if (fWeights) delete fWeights;
0116859c 110}
111
72bb0bb7 112AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(Int_t ipos){
113 //
114 //
115 //
116 TObjArray *arr = (TObjArray*)fCorrections;
117 return (AliTPCCorrection *)arr->At(ipos);
118}
119
120AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(const char *cname){
121 //
122 //
123 //
124 TCollection *arr = fCorrections;
125 return (AliTPCCorrection *)arr->FindObject(cname);
126}
127
128
0116859c 129
130void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
131 //
132 // This applies all correction and the specified manner (see general
133 // class description for details).
134 //
c9cbd2f2 135
136 if (!fCorrections) {
137 AliInfo("No Corrections-models were set: can not calculate distortions");
138 return;
139 }
cfe2c39a 140 TIterator *i=fCorrections->MakeIterator();
0116859c 141 AliTPCCorrection *c;
cfe2c39a 142 Int_t weightIndex=0;
0116859c 143 switch (fMode) {
144 case kParallel:
145 Float_t dxi[3];
146 for (int j=0;j<3;++j) dx[j]=0.;
147 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
148 c->GetCorrection(x,roc,dxi);
cfe2c39a 149 Double_t w=1;
150 if (fWeights) w=(*fWeights)[weightIndex++];
151 for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
0116859c 152 }
153 break;
154 case kQueue:
155 Float_t xi[3];
156 for (Int_t j=0;j<3;++j) xi[j]=x[j];
157 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
158 c->GetCorrection(xi,roc,dx);
cfe2c39a 159 Double_t w=1;
160 if (fWeights) w=(*fWeights)[weightIndex++];
161 for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
0116859c 162 }
163 for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
164 break;
0f236b4e 165 case kQueueResidual:
166 //TODO: for the moment assume inverse of distortion
167 // check if this is what is desired
168 GetDistortion(x,roc,dx);
169 for (Int_t j=0;j<3;++j) dx[j]*=-1.;
170 break;
0116859c 171 }
172 delete i;
173}
174
175void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
176 //
177 // This applies all distortions and the specified manner (see general
178 // class descxiption for details).
179 //
180
c9cbd2f2 181 if (!fCorrections) {
182 AliInfo("No Corrections-models were set: can not calculate distortions");
183 return;
184 }
0f236b4e 185
186 if (fMode==kQueueResidual && !fWeights) {
187 AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead.");
188 fMode=kQueue;
189 }
190
0116859c 191 TIterator *i=fCorrections->MakeReverseIterator();
192 AliTPCCorrection *c;
cfe2c39a 193 Int_t weightIndex=0;
0116859c 194 switch (fMode) {
195 case kParallel:
196 Float_t dxi[3];
197 for (int j=0;j<3;++j) dx[j]=0.;
198 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
199 c->GetDistortion(x,roc,dxi);
cfe2c39a 200 Double_t w=1;
201 if (fWeights) w=(*fWeights)[weightIndex++];
202 for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
0116859c 203 }
204 break;
205 case kQueue:
206 Float_t xi[3];
207 for (Int_t j=0;j<3;++j) xi[j]=x[j];
208 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
209 c->GetDistortion(xi,roc,dx);
cfe2c39a 210 Double_t w=1;
211 if (fWeights) w=(*fWeights)[weightIndex++];
212 for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
0116859c 213 }
214 for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
215 break;
0f236b4e 216 case kQueueResidual:
217 Float_t xi2[3];
218 for (Int_t j=0;j<3;++j) xi2[j]=x[j];
219 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
220 Double_t w=(*fWeights)[weightIndex++];
221 if (w>0) c->GetDistortion(xi2,roc,dx);
222 else c->GetCorrection(xi2,roc,dx);
223 for (Int_t j=0;j<3;++j) xi2[j]+=TMath::Abs(w)*dx[j];
224 }
225 for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j];
226 break;
0116859c 227 }
228 delete i;
229}
230
231
232void AliTPCComposedCorrection::Print(Option_t* option) const {
233 //
234 // Print function to check which correction classes are used
235 // option=="d" prints details regarding the setted magnitude
236 // option=="a" prints the C0 and C1 coefficents for calibration purposes
237 //
238
239 printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle());
240 TString opt = option; opt.ToLower();
241 Int_t in=1;
c9cbd2f2 242 if (!fCorrections) {
243 printf(" - composed correction is empty!\n");
244 return;
245 }
0116859c 246 TIterator *i=fCorrections->MakeIterator();
247 AliTPCCorrection *c;
248 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
249 if (opt.Contains("d")) {
0b736a46 250 printf("\n");
251 printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
0116859c 252 c->Print(option);
253 } else {
0b736a46 254 printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
0116859c 255 }
256 ++in;
257 }
e527a1b9 258 if (in==1) printf(" Info: The correction compound is empty: No corrections set\n");
0116859c 259 delete i;
260}
261
262
e527a1b9 263void AliTPCComposedCorrection::Init() {
264 //
265 // Initialization funtion (not used at the moment)
266 //
c9cbd2f2 267 if (!fCorrections) {
268 AliInfo("No Correction-models were set");
269 return;
270 }
e527a1b9 271 TIterator *i=fCorrections->MakeIterator();
272 AliTPCCorrection *c;
273 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
274 c->Init();
275 delete i;
276
277}
278
279void AliTPCComposedCorrection::Update(const TTimeStamp &timeStamp) {
280 //
281 // Update function
282 //
c9cbd2f2 283 if (!fCorrections) {
284 AliInfo("No Correction-models were set");
285 return;
286 }
e527a1b9 287
288 TIterator *i=fCorrections->MakeIterator();
289 AliTPCCorrection *c;
290 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
291 c->Update(timeStamp);
292 delete i;
293
294}
295
296
297
0116859c 298void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
299 //
300 // Gives the possibility to set the OmegaTau plus Tensor corrections T1 and T2 (effective omega Tau)
301 // to each subcorrection (since they might become event specific due to changing drift velocity)
302 //
303 // The omegaTau comes idealy from the Database, since it is a function of drift velocity, B and E field
304 // e.g. omegaTau = -10.0 * Bz * vdrift / Ez ; // with Bz in kG and Ez in V/cm
305 // omegaTau = -0.325 for Bz=5kG, Ez=400V/cm and vdrift = 2.6cm/muSec
306 // The T1 and T2 tensors were measured in a dedicated calibration run
307 //
308 // Note: overwrites previously set values!
309 //
310
c9cbd2f2 311 if (!fCorrections) {
312 AliInfo("No Correction-models were set");
313 return;
314 }
315
0116859c 316 TIterator *i=fCorrections->MakeIterator();
317 AliTPCCorrection *c;
318 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
319 c->SetOmegaTauT1T2(omegaTau,t1,t2);
320 }
321 delete i;
322}
323
324ClassImp(AliTPCComposedCorrection)