]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/TPCbase/AliTPCComposedCorrection.cxx
ATO-98 AddCorrectionCompact - Bug fix check fWeights pointer
[u/mrichter/AliRoot.git] / TPC / TPCbase / AliTPCComposedCorrection.cxx
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.                                                            //
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
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>
62 #include <TTimeStamp.h>
63 #include <TIterator.h>
64 #include <TMath.h>
65 #include "AliLog.h"
66
67 #include "AliTPCComposedCorrection.h"
68
69
70 AliTPCComposedCorrection::AliTPCComposedCorrection() 
71   : AliTPCCorrection("composed_correction",
72                      "composition of corrections"),
73     fCorrections(0),
74     fMode(kParallel),
75     fWeights(0)  // weights of corrections
76 {
77   //
78   // default constructor
79   //
80 }
81
82 AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections,
83                                                    AliTPCComposedCorrection::CompositionType mode)
84   : AliTPCCorrection("composed_correction",
85                      "composition of corrections"),
86     fCorrections(corrections),
87     fMode(mode),
88     fWeights(0) //weights of correction
89 {
90   //
91   // Constructor that defines the set of corrections, this one is composed of.
92   //
93 }
94
95 AliTPCComposedCorrection::~AliTPCComposedCorrection() {
96   // 
97   // destructor
98   //
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   }
109   if (fWeights) delete fWeights;
110 }
111
112
113 Bool_t AliTPCComposedCorrection::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
114   //
115   // Add correction  - better name needed (left/right) - for the moment I assumme they commute
116   // Why not to just use array of corrections - CPU consideration
117   // Assumptions:
118   //  - origin of distortion/correction are additive
119   //  - corrections/distortion are small   and they commute
120   //  - only correction ot the same type supported 
121   const Int_t knCorr=100;
122   if (corr==NULL) {
123     AliError("Zerro pointer - correction");
124     return kFALSE;
125   }
126   if (!fCorrections) fCorrections= new TObjArray(knCorr);
127   // 1.) Case of  Composed correction
128   AliTPCComposedCorrection * corrC = dynamic_cast<AliTPCComposedCorrection *>(corr);
129   if (corrC){
130     Int_t ncorrs= corrC->fCorrections->GetEntries();
131     Bool_t isOK=kTRUE;
132     for (Int_t icorr=0; icorr<ncorrs; icorr++){
133       Double_t weight0=((corrC->fWeights)==NULL)?1:(*(corrC->fWeights))[icorr];
134       isOK&=AddCorrectionCompact(corrC->GetSubCorrection(icorr),weight*weight0);
135     }
136     return isOK;
137   }
138   // 2.) Find subcorrection of the same type
139   AliTPCCorrection * toAdd=0;
140   Int_t ncorr=fCorrections->GetEntries();
141   for (Int_t icorr=0; icorr<ncorr; icorr++){
142     if (GetSubCorrection(icorr)==NULL)  continue;
143     if (GetSubCorrection(icorr)->IsA()==corr->IsA())  toAdd=GetSubCorrection(icorr);
144   }
145   // 3.) create of givent type  if does not exist 
146   if (toAdd==NULL){
147     toAdd= (AliTPCCorrection*)((corr->IsA())->New());
148     fCorrections->Add(toAdd);
149   }
150   // 4.) add to object of given type 
151   return toAdd->AddCorrectionCompact(corr, weight);
152 }
153
154
155 AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(Int_t ipos){
156   //
157   //
158   //
159   TObjArray *arr = (TObjArray*)fCorrections;
160   return (AliTPCCorrection *)arr->At(ipos);
161 }
162
163 AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(const char *cname){
164   //
165   //
166   //
167   TCollection *arr = fCorrections;
168   return (AliTPCCorrection *)arr->FindObject(cname);
169 }
170
171
172
173 void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
174   //
175   // This applies all correction and the specified manner (see general
176   // class description for details).
177   //
178
179   if (!fCorrections) {
180     AliInfo("No Corrections-models were set: can not calculate distortions");
181     return;
182   }
183   TIterator *i=fCorrections->MakeIterator();
184   AliTPCCorrection *c;
185   Int_t weightIndex=0;
186   switch (fMode) {
187   case kParallel:
188     Float_t dxi[3];
189     for (int j=0;j<3;++j) dx[j]=0.;
190     while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
191       c->GetCorrection(x,roc,dxi);
192       Double_t w=1;
193       if (fWeights) w=(*fWeights)[weightIndex++];
194       for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
195     }
196     break;
197   case kQueue:
198     Float_t xi[3];
199     for (Int_t j=0;j<3;++j) xi[j]=x[j];
200     while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
201       c->GetCorrection(xi,roc,dx);
202       Double_t w=1;
203       if (fWeights) w=(*fWeights)[weightIndex++];
204       for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
205     }
206     for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
207     break;
208   case kQueueResidual:
209     //TODO: for the moment assume inverse of distortion
210     //      check if this is what is desired
211     GetDistortion(x,roc,dx);
212     for (Int_t j=0;j<3;++j) dx[j]*=-1.;
213     break;
214   }
215   delete i;
216 }
217
218 void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
219   //
220   // This applies all distortions and the specified manner (see general
221   // class descxiption for details).
222   //
223
224   if (!fCorrections) {
225     AliInfo("No Corrections-models were set: can not calculate distortions");
226     return;
227   }
228   
229   if (fMode==kQueueResidual && !fWeights) {
230     AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead.");
231     fMode=kQueue;
232   }
233   
234   TIterator *i=fCorrections->MakeReverseIterator();
235   AliTPCCorrection *c;
236   Int_t weightIndex=0;
237   switch (fMode) {
238   case kParallel:
239     Float_t dxi[3];
240     for (int j=0;j<3;++j) dx[j]=0.;
241     while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
242       c->GetDistortion(x,roc,dxi);
243       Double_t w=1;
244       if (fWeights) w=(*fWeights)[weightIndex++];
245       for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
246     }
247     break;
248   case kQueue:
249     Float_t xi[3];
250     for (Int_t j=0;j<3;++j) xi[j]=x[j];
251     while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
252       c->GetDistortion(xi,roc,dx);
253       Double_t w=1;
254       if (fWeights) w=(*fWeights)[weightIndex++];
255       for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
256     }
257     for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
258     break;
259   case kQueueResidual:
260     Float_t xi2[3];
261     for (Int_t j=0;j<3;++j) xi2[j]=x[j];
262     while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
263       Double_t w=(*fWeights)[weightIndex++];
264       if (w>0) c->GetDistortion(xi2,roc,dx);
265       else c->GetCorrection(xi2,roc,dx);
266       for (Int_t j=0;j<3;++j) xi2[j]+=TMath::Abs(w)*dx[j];
267     }
268     for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j];
269     break;
270   }
271   delete i;
272 }
273
274
275 void AliTPCComposedCorrection::Print(Option_t* option) const {
276   //
277   // Print function to check which correction classes are used 
278   // option=="d" prints details regarding the setted magnitude 
279   // option=="a" prints the C0 and C1 coefficents for calibration purposes
280   //
281
282   printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle());
283   TString opt = option; opt.ToLower();
284   Int_t in=1;
285   if (!fCorrections) {
286     printf("   - composed correction is empty!\n");
287     return;
288   }
289   TIterator *i=fCorrections->MakeIterator();
290   AliTPCCorrection *c;
291   while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
292     if (opt.Contains("d")) {
293       printf("\n");
294       printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
295       c->Print(option);
296     } else {
297       printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
298     }
299     ++in;
300   }
301   if (in==1) printf("  Info: The correction compound is empty: No corrections set\n");
302   delete i;
303 }
304
305
306 void AliTPCComposedCorrection::Init() {
307   //
308   // Initialization funtion (not used at the moment)
309   //
310   if (!fCorrections) {
311     AliInfo("No Correction-models were set");
312     return;
313   }
314   TIterator *i=fCorrections->MakeIterator();
315   AliTPCCorrection *c;
316   while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) 
317     c->Init();
318   delete i;
319   
320 }
321
322 void AliTPCComposedCorrection::Update(const TTimeStamp &timeStamp) {
323   //
324   // Update function 
325   //
326   if (!fCorrections) {
327     AliInfo("No Correction-models were set");
328     return;
329   }
330
331   TIterator *i=fCorrections->MakeIterator();
332   AliTPCCorrection *c;
333   while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) 
334     c->Update(timeStamp);
335   delete i;
336  
337 }
338
339
340
341 void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
342   //
343   // Gives the possibility to set the OmegaTau plus Tensor corrections T1 and T2 (effective omega Tau)
344   // to each subcorrection (since they might become event specific due to changing drift velocity)
345   //
346   // The omegaTau comes idealy from the Database, since it is a function of drift velocity, B and E field 
347   // e.g. omegaTau  = -10.0 * Bz * vdrift / Ez ; // with Bz in kG and Ez in V/cm
348   //      omegaTau  = -0.325 for Bz=5kG, Ez=400V/cm and vdrift = 2.6cm/muSec
349   // The T1 and T2 tensors were measured in a dedicated calibration run
350   //
351   // Note: overwrites previously set values!
352   // 
353
354   if (!fCorrections) {
355     AliInfo("No Correction-models were set");
356     return;
357   }
358
359   TIterator *i=fCorrections->MakeIterator();
360   AliTPCCorrection *c;
361   while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
362     c->SetOmegaTauT1T2(omegaTau,t1,t2);
363   }
364   delete i;
365 }
366
367 ClassImp(AliTPCComposedCorrection)