Line data Source code
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 : /// \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
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 9 : : AliTPCCorrection("composed_correction",
72 : "composition of corrections"),
73 9 : fCorrections(0),
74 9 : fMode(kParallel),
75 9 : fWeights(0) // weights of corrections
76 45 : {
77 : /// default constructor
78 :
79 18 : }
80 :
81 : AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections,
82 : AliTPCComposedCorrection::CompositionType mode)
83 0 : : AliTPCCorrection("composed_correction",
84 : "composition of corrections"),
85 0 : fCorrections(corrections),
86 0 : fMode(mode),
87 0 : fWeights(0) //weights of correction
88 0 : {
89 : /// Constructor that defines the set of corrections, this one is composed of.
90 :
91 0 : }
92 :
93 0 : AliTPCComposedCorrection::~AliTPCComposedCorrection() {
94 : /// destructor
95 :
96 0 : if (!fCorrections) {
97 0 : AliInfo("No Correction-models were set: can not delete them");
98 : } else {
99 0 : TIterator *i=fCorrections->MakeIterator();
100 : AliTPCCorrection *c;
101 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
102 0 : delete c;
103 : }
104 0 : delete i;
105 : }
106 0 : if (fWeights) delete fWeights;
107 0 : }
108 :
109 :
110 : Bool_t AliTPCComposedCorrection::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
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 :
118 : const Int_t knCorr=100;
119 0 : if (corr==NULL) {
120 0 : AliError("Zerro pointer - correction");
121 0 : return kFALSE;
122 : }
123 0 : if (!fCorrections) fCorrections= new TObjArray(knCorr);
124 : // 1.) Case of Composed correction
125 0 : AliTPCComposedCorrection * corrC = dynamic_cast<AliTPCComposedCorrection *>(corr);
126 0 : if (corrC){
127 0 : Int_t ncorrs= corrC->fCorrections->GetEntries();
128 : Bool_t isOK=kTRUE;
129 0 : for (Int_t icorr=0; icorr<ncorrs; icorr++){
130 0 : Double_t weight0=((corrC->fWeights)==NULL)?1:(*(corrC->fWeights))[icorr];
131 0 : isOK&=AddCorrectionCompact(corrC->GetSubCorrection(icorr),weight*weight0);
132 : }
133 0 : return isOK;
134 : }
135 : // 2.) Find subcorrection of the same type
136 : AliTPCCorrection * toAdd=0;
137 0 : Int_t ncorr=fCorrections->GetEntries();
138 0 : for (Int_t icorr=0; icorr<ncorr; icorr++){
139 0 : if (GetSubCorrection(icorr)==NULL) continue;
140 0 : if (GetSubCorrection(icorr)->IsA()==corr->IsA()) toAdd=GetSubCorrection(icorr);
141 : }
142 : // 3.) create of givent type if does not exist
143 0 : if (toAdd==NULL){
144 0 : toAdd= (AliTPCCorrection*)((corr->IsA())->New());
145 0 : fCorrections->Add(toAdd);
146 0 : }
147 : // 4.) add to object of given type
148 0 : return toAdd->AddCorrectionCompact(corr, weight);
149 0 : }
150 :
151 :
152 : AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(Int_t ipos){
153 : ///
154 :
155 0 : TObjArray *arr = (TObjArray*)fCorrections;
156 0 : return (AliTPCCorrection *)arr->At(ipos);
157 : }
158 :
159 : AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(const char *cname){
160 : ///
161 :
162 0 : TCollection *arr = fCorrections;
163 0 : return (AliTPCCorrection *)arr->FindObject(cname);
164 : }
165 :
166 :
167 :
168 : void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
169 : /// This applies all correction and the specified manner (see general
170 : /// class description for details).
171 :
172 0 : if (!fCorrections) {
173 0 : AliInfo("No Corrections-models were set: can not calculate distortions");
174 0 : return;
175 : }
176 0 : TIterator *i=fCorrections->MakeIterator();
177 : AliTPCCorrection *c;
178 : Int_t weightIndex=0;
179 0 : switch (fMode) {
180 : case kParallel:
181 0 : Float_t dxi[3];
182 0 : for (int j=0;j<3;++j) dx[j]=0.;
183 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
184 0 : c->GetCorrection(x,roc,dxi);
185 : Double_t w=1;
186 0 : if (fWeights) w=(*fWeights)[weightIndex++];
187 0 : for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
188 : }
189 0 : break;
190 : case kQueue:
191 0 : Float_t xi[3];
192 0 : for (Int_t j=0;j<3;++j) xi[j]=x[j];
193 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
194 0 : c->GetCorrection(xi,roc,dx);
195 : Double_t w=1;
196 0 : if (fWeights) w=(*fWeights)[weightIndex++];
197 0 : for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
198 : }
199 0 : for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
200 0 : break;
201 : case kQueueResidual:
202 : //TODO: for the moment assume inverse of distortion
203 : // check if this is what is desired
204 0 : GetDistortion(x,roc,dx);
205 0 : for (Int_t j=0;j<3;++j) dx[j]*=-1.;
206 0 : break;
207 0 : }
208 0 : delete i;
209 0 : }
210 :
211 : void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
212 : /// This applies all distortions and the specified manner (see general
213 : /// class descxiption for details).
214 :
215 0 : if (!fCorrections) {
216 0 : AliInfo("No Corrections-models were set: can not calculate distortions");
217 0 : return;
218 : }
219 :
220 0 : if (fMode==kQueueResidual && !fWeights) {
221 0 : AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead.");
222 0 : fMode=kQueue;
223 0 : }
224 :
225 0 : TIterator *i=fCorrections->MakeReverseIterator();
226 : AliTPCCorrection *c;
227 : Int_t weightIndex=0;
228 0 : switch (fMode) {
229 : case kParallel:
230 0 : Float_t dxi[3];
231 0 : for (int j=0;j<3;++j) dx[j]=0.;
232 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
233 0 : c->GetDistortion(x,roc,dxi);
234 : Double_t w=1;
235 0 : if (fWeights) w=(*fWeights)[weightIndex++];
236 0 : for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
237 : }
238 0 : break;
239 : case kQueue:
240 0 : Float_t xi[3];
241 0 : for (Int_t j=0;j<3;++j) xi[j]=x[j];
242 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
243 0 : c->GetDistortion(xi,roc,dx);
244 : Double_t w=1;
245 0 : if (fWeights) w=(*fWeights)[weightIndex++];
246 0 : for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
247 : }
248 0 : for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
249 0 : break;
250 : case kQueueResidual:
251 0 : Float_t xi2[3];
252 0 : for (Int_t j=0;j<3;++j) xi2[j]=x[j];
253 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
254 0 : Double_t w=(*fWeights)[weightIndex++];
255 0 : if (w>0) c->GetDistortion(xi2,roc,dx);
256 0 : else c->GetCorrection(xi2,roc,dx);
257 0 : for (Int_t j=0;j<3;++j) xi2[j]+=TMath::Abs(w)*dx[j];
258 : }
259 0 : for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j];
260 : break;
261 0 : }
262 0 : delete i;
263 0 : }
264 :
265 :
266 : void AliTPCComposedCorrection::Print(Option_t* option) const {
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
270 :
271 0 : printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle());
272 0 : TString opt = option; opt.ToLower();
273 : Int_t in=1;
274 0 : if (!fCorrections) {
275 0 : printf(" - composed correction is empty!\n");
276 0 : return;
277 : }
278 0 : TIterator *i=fCorrections->MakeIterator();
279 : AliTPCCorrection *c;
280 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
281 0 : if (opt.Contains("d")) {
282 0 : printf("\n");
283 0 : printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
284 0 : c->Print(option);
285 : } else {
286 0 : printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
287 : }
288 0 : ++in;
289 : }
290 0 : if (in==1) printf(" Info: The correction compound is empty: No corrections set\n");
291 0 : delete i;
292 0 : }
293 :
294 :
295 : void AliTPCComposedCorrection::Init() {
296 : /// Initialization funtion (not used at the moment)
297 :
298 18 : if (!fCorrections) {
299 0 : AliInfo("No Correction-models were set");
300 0 : return;
301 : }
302 9 : TIterator *i=fCorrections->MakeIterator();
303 : AliTPCCorrection *c;
304 147 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
305 30 : c->Init();
306 18 : delete i;
307 :
308 18 : }
309 :
310 : void AliTPCComposedCorrection::Update(const TTimeStamp &timeStamp) {
311 : /// Update function
312 :
313 0 : if (!fCorrections) {
314 0 : AliInfo("No Correction-models were set");
315 0 : return;
316 : }
317 :
318 0 : TIterator *i=fCorrections->MakeIterator();
319 : AliTPCCorrection *c;
320 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
321 0 : c->Update(timeStamp);
322 0 : delete i;
323 :
324 0 : }
325 :
326 :
327 :
328 : void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
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!
338 :
339 0 : if (!fCorrections) {
340 0 : AliInfo("No Correction-models were set");
341 0 : return;
342 : }
343 :
344 0 : TIterator *i=fCorrections->MakeIterator();
345 : AliTPCCorrection *c;
346 0 : while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
347 0 : c->SetOmegaTauT1T2(omegaTau,t1,t2);
348 : }
349 0 : delete i;
350 0 : }
351 :
352 : /// \cond CLASSIMP
353 24 : ClassImp(AliTPCComposedCorrection)
354 : /// \endcond
|