]>
Commit | Line | Data |
---|---|---|
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 | ||
7d855b04 | 17 | /// \class AliTPCComposedCorrection |
18 | /// \brief AliTPCComposedCorrection class | |
19 | /// | |
20 | /// This class is creating a correction that is composed out of smaller | |
21 | /// corrections. | |
22 | /// There are two ways the sub-corrections can be combined into this one: | |
23 | /// 1. kParallel: All corrections are applied at the given position x and | |
24 | /// the dx terms are summed up (this commutes). | |
25 | /// 2. kQueue: The corrections are called in order. The first one at the | |
26 | /// given position x resulting in dx1, the second one is called at | |
27 | /// the corrected position (x+dx1) resulting in dx2, the third one | |
28 | /// is then called at position (x+dx1+dx2) and so forth. dx=dx1+dx2+... | |
29 | /// is returned. | |
30 | /// 3. kQueueResidual: like kQueue with the exception that in case of | |
31 | /// a positive weight the 'Distortion' is called and in case of a negative | |
32 | /// weight the 'Correction' is called, where the absolute of the weight | |
33 | /// will be applied to the correction | |
34 | /// For the inverse of the correction this is taken into account by reversing | |
35 | /// the order the corrections are applied in the kQueue case (no issue for | |
36 | /// kParallel). | |
37 | /// | |
38 | /// Example usage: | |
39 | /// | |
40 | /// ~~~{.cpp} | |
41 | /// AliMagF mag("mag","mag"); | |
42 | /// AliTPCExBBShape exb; // B field shape distortions | |
43 | /// exb.SetBField(&mag); | |
44 | /// | |
45 | /// AliTPCExBTwist twist; // ExB Twist distortions | |
46 | /// twist.SetXTwist(0.001); | |
47 | /// | |
48 | /// TObjArray cs; cs.Add(&exb); cs.Add(&twist); | |
49 | /// | |
50 | /// AliTPCComposedCorrection cc; | |
51 | /// cc.SetCorrections(&cs); | |
52 | /// cc.SetOmegaTauT1T2(wt,T1,T2); | |
53 | /// cc.Print("DA"); | |
54 | /// cc.CreateHistoDRPhiinZR(0,100,100)->Draw("surf2"); | |
55 | /// ~~~ | |
56 | /// | |
57 | /// \author Magnus Mager, Stefan Rossegger, Jim Thomas | |
58 | /// \date 27/04/2010 | |
0116859c | 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 | ||
7d855b04 | 70 | AliTPCComposedCorrection::AliTPCComposedCorrection() |
0116859c | 71 | : AliTPCCorrection("composed_correction", |
72 | "composition of corrections"), | |
73 | fCorrections(0), | |
cfe2c39a | 74 | fMode(kParallel), |
75 | fWeights(0) // weights of corrections | |
0116859c | 76 | { |
7d855b04 | 77 | /// default constructor |
78 | ||
0116859c | 79 | } |
80 | ||
81 | AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections, | |
82 | AliTPCComposedCorrection::CompositionType mode) | |
83 | : AliTPCCorrection("composed_correction", | |
84 | "composition of corrections"), | |
85 | fCorrections(corrections), | |
cfe2c39a | 86 | fMode(mode), |
87 | fWeights(0) //weights of correction | |
0116859c | 88 | { |
7d855b04 | 89 | /// Constructor that defines the set of corrections, this one is composed of. |
90 | ||
0116859c | 91 | } |
92 | ||
93 | AliTPCComposedCorrection::~AliTPCComposedCorrection() { | |
7d855b04 | 94 | /// destructor |
95 | ||
c9cbd2f2 | 96 | if (!fCorrections) { |
97 | AliInfo("No Correction-models were set: can not delete them"); | |
98 | } else { | |
99 | TIterator *i=fCorrections->MakeIterator(); | |
100 | AliTPCCorrection *c; | |
101 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
102 | delete c; | |
103 | } | |
104 | delete i; | |
105 | } | |
cfe2c39a | 106 | if (fWeights) delete fWeights; |
0116859c | 107 | } |
108 | ||
69d03c4d | 109 | |
110 | Bool_t AliTPCComposedCorrection::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){ | |
7d855b04 | 111 | /// Add correction - better name needed (left/right) - for the moment I assumme they commute |
112 | /// Why not to just use array of corrections - CPU consideration | |
113 | /// Assumptions: | |
114 | /// - origin of distortion/correction are additive | |
115 | /// - corrections/distortion are small and they commute | |
116 | /// - only correction ot the same type supported | |
117 | ||
69d03c4d | 118 | const Int_t knCorr=100; |
119 | if (corr==NULL) { | |
120 | AliError("Zerro pointer - correction"); | |
121 | return kFALSE; | |
122 | } | |
123 | if (!fCorrections) fCorrections= new TObjArray(knCorr); | |
124 | // 1.) Case of Composed correction | |
125 | AliTPCComposedCorrection * corrC = dynamic_cast<AliTPCComposedCorrection *>(corr); | |
126 | if (corrC){ | |
127 | Int_t ncorrs= corrC->fCorrections->GetEntries(); | |
128 | Bool_t isOK=kTRUE; | |
129 | for (Int_t icorr=0; icorr<ncorrs; icorr++){ | |
2c8bf938 | 130 | Double_t weight0=((corrC->fWeights)==NULL)?1:(*(corrC->fWeights))[icorr]; |
131 | isOK&=AddCorrectionCompact(corrC->GetSubCorrection(icorr),weight*weight0); | |
69d03c4d | 132 | } |
133 | return isOK; | |
134 | } | |
135 | // 2.) Find subcorrection of the same type | |
136 | AliTPCCorrection * toAdd=0; | |
137 | Int_t ncorr=fCorrections->GetEntries(); | |
138 | for (Int_t icorr=0; icorr<ncorr; icorr++){ | |
139 | if (GetSubCorrection(icorr)==NULL) continue; | |
140 | if (GetSubCorrection(icorr)->IsA()==corr->IsA()) toAdd=GetSubCorrection(icorr); | |
141 | } | |
7d855b04 | 142 | // 3.) create of givent type if does not exist |
69d03c4d | 143 | if (toAdd==NULL){ |
144 | toAdd= (AliTPCCorrection*)((corr->IsA())->New()); | |
145 | fCorrections->Add(toAdd); | |
146 | } | |
7d855b04 | 147 | // 4.) add to object of given type |
69d03c4d | 148 | return toAdd->AddCorrectionCompact(corr, weight); |
149 | } | |
150 | ||
151 | ||
72bb0bb7 | 152 | AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(Int_t ipos){ |
7d855b04 | 153 | /// |
154 | ||
72bb0bb7 | 155 | TObjArray *arr = (TObjArray*)fCorrections; |
156 | return (AliTPCCorrection *)arr->At(ipos); | |
157 | } | |
158 | ||
159 | AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(const char *cname){ | |
7d855b04 | 160 | /// |
161 | ||
72bb0bb7 | 162 | TCollection *arr = fCorrections; |
163 | return (AliTPCCorrection *)arr->FindObject(cname); | |
164 | } | |
165 | ||
166 | ||
0116859c | 167 | |
168 | void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) { | |
7d855b04 | 169 | /// This applies all correction and the specified manner (see general |
170 | /// class description for details). | |
c9cbd2f2 | 171 | |
172 | if (!fCorrections) { | |
173 | AliInfo("No Corrections-models were set: can not calculate distortions"); | |
174 | return; | |
175 | } | |
cfe2c39a | 176 | TIterator *i=fCorrections->MakeIterator(); |
0116859c | 177 | AliTPCCorrection *c; |
cfe2c39a | 178 | Int_t weightIndex=0; |
0116859c | 179 | switch (fMode) { |
180 | case kParallel: | |
181 | Float_t dxi[3]; | |
182 | for (int j=0;j<3;++j) dx[j]=0.; | |
183 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
184 | c->GetCorrection(x,roc,dxi); | |
cfe2c39a | 185 | Double_t w=1; |
186 | if (fWeights) w=(*fWeights)[weightIndex++]; | |
187 | for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j]; | |
0116859c | 188 | } |
189 | break; | |
190 | case kQueue: | |
191 | Float_t xi[3]; | |
192 | for (Int_t j=0;j<3;++j) xi[j]=x[j]; | |
193 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
194 | c->GetCorrection(xi,roc,dx); | |
cfe2c39a | 195 | Double_t w=1; |
196 | if (fWeights) w=(*fWeights)[weightIndex++]; | |
197 | for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j]; | |
0116859c | 198 | } |
199 | for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j]; | |
200 | break; | |
0f236b4e | 201 | case kQueueResidual: |
202 | //TODO: for the moment assume inverse of distortion | |
203 | // check if this is what is desired | |
204 | GetDistortion(x,roc,dx); | |
205 | for (Int_t j=0;j<3;++j) dx[j]*=-1.; | |
206 | break; | |
0116859c | 207 | } |
208 | delete i; | |
209 | } | |
210 | ||
211 | void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) { | |
7d855b04 | 212 | /// This applies all distortions and the specified manner (see general |
213 | /// class descxiption for details). | |
0116859c | 214 | |
c9cbd2f2 | 215 | if (!fCorrections) { |
216 | AliInfo("No Corrections-models were set: can not calculate distortions"); | |
217 | return; | |
218 | } | |
7d855b04 | 219 | |
0f236b4e | 220 | if (fMode==kQueueResidual && !fWeights) { |
221 | AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead."); | |
222 | fMode=kQueue; | |
223 | } | |
7d855b04 | 224 | |
0116859c | 225 | TIterator *i=fCorrections->MakeReverseIterator(); |
226 | AliTPCCorrection *c; | |
cfe2c39a | 227 | Int_t weightIndex=0; |
0116859c | 228 | switch (fMode) { |
229 | case kParallel: | |
230 | Float_t dxi[3]; | |
231 | for (int j=0;j<3;++j) dx[j]=0.; | |
232 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
233 | c->GetDistortion(x,roc,dxi); | |
cfe2c39a | 234 | Double_t w=1; |
235 | if (fWeights) w=(*fWeights)[weightIndex++]; | |
236 | for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j]; | |
0116859c | 237 | } |
238 | break; | |
239 | case kQueue: | |
240 | Float_t xi[3]; | |
241 | for (Int_t j=0;j<3;++j) xi[j]=x[j]; | |
242 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
243 | c->GetDistortion(xi,roc,dx); | |
cfe2c39a | 244 | Double_t w=1; |
245 | if (fWeights) w=(*fWeights)[weightIndex++]; | |
246 | for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j]; | |
0116859c | 247 | } |
248 | for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j]; | |
249 | break; | |
0f236b4e | 250 | case kQueueResidual: |
251 | Float_t xi2[3]; | |
252 | for (Int_t j=0;j<3;++j) xi2[j]=x[j]; | |
253 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
254 | Double_t w=(*fWeights)[weightIndex++]; | |
255 | if (w>0) c->GetDistortion(xi2,roc,dx); | |
256 | else c->GetCorrection(xi2,roc,dx); | |
257 | for (Int_t j=0;j<3;++j) xi2[j]+=TMath::Abs(w)*dx[j]; | |
258 | } | |
259 | for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j]; | |
260 | break; | |
0116859c | 261 | } |
262 | delete i; | |
263 | } | |
264 | ||
265 | ||
266 | void AliTPCComposedCorrection::Print(Option_t* option) const { | |
7d855b04 | 267 | /// Print function to check which correction classes are used |
268 | /// option=="d" prints details regarding the setted magnitude | |
269 | /// option=="a" prints the C0 and C1 coefficents for calibration purposes | |
0116859c | 270 | |
271 | printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle()); | |
272 | TString opt = option; opt.ToLower(); | |
273 | Int_t in=1; | |
c9cbd2f2 | 274 | if (!fCorrections) { |
275 | printf(" - composed correction is empty!\n"); | |
276 | return; | |
277 | } | |
0116859c | 278 | TIterator *i=fCorrections->MakeIterator(); |
279 | AliTPCCorrection *c; | |
280 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
281 | if (opt.Contains("d")) { | |
0b736a46 | 282 | printf("\n"); |
283 | printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName()); | |
0116859c | 284 | c->Print(option); |
285 | } else { | |
0b736a46 | 286 | printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName()); |
0116859c | 287 | } |
288 | ++in; | |
289 | } | |
e527a1b9 | 290 | if (in==1) printf(" Info: The correction compound is empty: No corrections set\n"); |
0116859c | 291 | delete i; |
292 | } | |
293 | ||
294 | ||
e527a1b9 | 295 | void AliTPCComposedCorrection::Init() { |
7d855b04 | 296 | /// Initialization funtion (not used at the moment) |
297 | ||
c9cbd2f2 | 298 | if (!fCorrections) { |
299 | AliInfo("No Correction-models were set"); | |
300 | return; | |
301 | } | |
e527a1b9 | 302 | TIterator *i=fCorrections->MakeIterator(); |
303 | AliTPCCorrection *c; | |
7d855b04 | 304 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) |
e527a1b9 | 305 | c->Init(); |
306 | delete i; | |
7d855b04 | 307 | |
e527a1b9 | 308 | } |
309 | ||
310 | void AliTPCComposedCorrection::Update(const TTimeStamp &timeStamp) { | |
7d855b04 | 311 | /// Update function |
312 | ||
c9cbd2f2 | 313 | if (!fCorrections) { |
314 | AliInfo("No Correction-models were set"); | |
315 | return; | |
316 | } | |
e527a1b9 | 317 | |
318 | TIterator *i=fCorrections->MakeIterator(); | |
319 | AliTPCCorrection *c; | |
7d855b04 | 320 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) |
e527a1b9 | 321 | c->Update(timeStamp); |
322 | delete i; | |
7d855b04 | 323 | |
e527a1b9 | 324 | } |
325 | ||
326 | ||
327 | ||
0116859c | 328 | void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) { |
7d855b04 | 329 | /// Gives the possibility to set the OmegaTau plus Tensor corrections T1 and T2 (effective omega Tau) |
330 | /// to each subcorrection (since they might become event specific due to changing drift velocity) | |
331 | /// | |
332 | /// The omegaTau comes idealy from the Database, since it is a function of drift velocity, B and E field | |
333 | /// e.g. omegaTau = -10.0 * Bz * vdrift / Ez ; // with Bz in kG and Ez in V/cm | |
334 | /// omegaTau = -0.325 for Bz=5kG, Ez=400V/cm and vdrift = 2.6cm/muSec | |
335 | /// The T1 and T2 tensors were measured in a dedicated calibration run | |
336 | /// | |
337 | /// Note: overwrites previously set values! | |
0116859c | 338 | |
c9cbd2f2 | 339 | if (!fCorrections) { |
340 | AliInfo("No Correction-models were set"); | |
341 | return; | |
342 | } | |
343 | ||
0116859c | 344 | TIterator *i=fCorrections->MakeIterator(); |
345 | AliTPCCorrection *c; | |
346 | while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) { | |
347 | c->SetOmegaTauT1T2(omegaTau,t1,t2); | |
348 | } | |
349 | delete i; | |
350 | } | |
351 | ||
7d855b04 | 352 | /// \cond CLASSIMP |
0116859c | 353 | ClassImp(AliTPCComposedCorrection) |
7d855b04 | 354 | /// \endcond |