2 /**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 ////////////////////////////////////////////////////////////////////////////////
19 // AliTPCComposedCorrection class //
21 // This class is creating a correction that is composed out of smaller //
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+... //
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 //
39 // date: 27/04/2010 //
40 // Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
44 // AliMagF mag("mag","mag"); //
45 // AliTPCExBBShape exb; // B field shape distortions //
46 // exb.SetBField(&mag); //
48 // AliTPCExBTwist twist; // ExB Twist distortions //
49 // twist.SetXTwist(0.001); //
51 // TObjArray cs; cs.Add(&exb); cs.Add(&twist); //
53 // AliTPCComposedCorrection cc; //
54 // cc.SetCorrections(&cs); //
55 // cc.SetOmegaTauT1T2(wt,T1,T2); //
57 // cc.CreateHistoDRPhiinZR(0,100,100)->Draw("surf2"); //
58 ////////////////////////////////////////////////////////////////////////////////
61 #include <TCollection.h>
62 #include <TTimeStamp.h>
63 #include <TIterator.h>
67 #include "AliTPCComposedCorrection.h"
70 AliTPCComposedCorrection::AliTPCComposedCorrection()
71 : AliTPCCorrection("composed_correction",
72 "composition of corrections"),
75 fWeights(0) // weights of corrections
78 // default constructor
82 AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections,
83 AliTPCComposedCorrection::CompositionType mode)
84 : AliTPCCorrection("composed_correction",
85 "composition of corrections"),
86 fCorrections(corrections),
88 fWeights(0) //weights of correction
91 // Constructor that defines the set of corrections, this one is composed of.
95 AliTPCComposedCorrection::~AliTPCComposedCorrection() {
100 AliInfo("No Correction-models were set: can not delete them");
102 TIterator *i=fCorrections->MakeIterator();
104 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
109 if (fWeights) delete fWeights;
113 Bool_t AliTPCComposedCorrection::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
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
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;
123 AliError("Zerro pointer - correction");
126 if (!fCorrections) fCorrections= new TObjArray(knCorr);
127 // 1.) Case of Composed correction
128 AliTPCComposedCorrection * corrC = dynamic_cast<AliTPCComposedCorrection *>(corr);
130 Int_t ncorrs= corrC->fCorrections->GetEntries();
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);
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);
145 // 3.) create of givent type if does not exist
147 toAdd= (AliTPCCorrection*)((corr->IsA())->New());
148 fCorrections->Add(toAdd);
150 // 4.) add to object of given type
151 return toAdd->AddCorrectionCompact(corr, weight);
155 AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(Int_t ipos){
159 TObjArray *arr = (TObjArray*)fCorrections;
160 return (AliTPCCorrection *)arr->At(ipos);
163 AliTPCCorrection * AliTPCComposedCorrection::GetSubCorrection(const char *cname){
167 TCollection *arr = fCorrections;
168 return (AliTPCCorrection *)arr->FindObject(cname);
173 void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
175 // This applies all correction and the specified manner (see general
176 // class description for details).
180 AliInfo("No Corrections-models were set: can not calculate distortions");
183 TIterator *i=fCorrections->MakeIterator();
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);
193 if (fWeights) w=(*fWeights)[weightIndex++];
194 for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
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);
203 if (fWeights) w=(*fWeights)[weightIndex++];
204 for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
206 for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
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.;
218 void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
220 // This applies all distortions and the specified manner (see general
221 // class descxiption for details).
225 AliInfo("No Corrections-models were set: can not calculate distortions");
229 if (fMode==kQueueResidual && !fWeights) {
230 AliInfo("kQueueResidual mode was selected but no weights were given. Switching to kQueue instead.");
234 TIterator *i=fCorrections->MakeReverseIterator();
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);
244 if (fWeights) w=(*fWeights)[weightIndex++];
245 for (Int_t j=0;j<3;++j) dx[j]+=w*dxi[j];
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);
254 if (fWeights) w=(*fWeights)[weightIndex++];
255 for (Int_t j=0;j<3;++j) xi[j]+=w*dx[j];
257 for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
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];
268 for (Int_t j=0;j<3;++j) dx[j]=xi2[j]-x[j];
275 void AliTPCComposedCorrection::Print(Option_t* option) const {
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
282 printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle());
283 TString opt = option; opt.ToLower();
286 printf(" - composed correction is empty!\n");
289 TIterator *i=fCorrections->MakeIterator();
291 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
292 if (opt.Contains("d")) {
294 printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
297 printf("%d. %s\t%s\n",in,c->GetTitle(), c->GetName());
301 if (in==1) printf(" Info: The correction compound is empty: No corrections set\n");
306 void AliTPCComposedCorrection::Init() {
308 // Initialization funtion (not used at the moment)
311 AliInfo("No Correction-models were set");
314 TIterator *i=fCorrections->MakeIterator();
316 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
322 void AliTPCComposedCorrection::Update(const TTimeStamp &timeStamp) {
327 AliInfo("No Correction-models were set");
331 TIterator *i=fCorrections->MakeIterator();
333 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next())))
334 c->Update(timeStamp);
341 void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
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)
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
351 // Note: overwrites previously set values!
355 AliInfo("No Correction-models were set");
359 TIterator *i=fCorrections->MakeIterator();
361 while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
362 c->SetOmegaTauT1T2(omegaTau,t1,t2);
367 ClassImp(AliTPCComposedCorrection)