1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
18 // Data container for relative ITS-TPC alignment analysis
19 // Holds an array of AliRelAlignerKalman objects
20 // and takes care of merging when processing data in parallel
22 // Origin: Mikolaj Krzewicki, Nikhef, Mikolaj.Krzewicki@cern.ch
24 //////////////////////////////////////////////////////////////////////////////
27 #include <TGraphErrors.h>
31 #include <TObjArray.h>
32 #include <TCollection.h>
33 #include <AliESDEvent.h>
34 #include "AliRelAlignerKalman.h"
35 #include "AliRelAlignerKalmanArray.h"
37 ClassImp(AliRelAlignerKalmanArray)
39 //______________________________________________________________________________
40 AliRelAlignerKalmanArray::AliRelAlignerKalmanArray():
41 TNamed("alignerArray","array of aligners"),
45 fOutRejSigmaOnMerge(10.),
46 fOutRejSigmaOnSmooth(1.),
52 //______________________________________________________________________________
53 AliRelAlignerKalmanArray::AliRelAlignerKalmanArray(Int_t t0, Int_t tend, Int_t slotwidth):
54 TNamed("alignerArray","array of aligners"),
56 fTimebinWidth(slotwidth),
58 fOutRejSigmaOnMerge(10.),
59 fOutRejSigmaOnSmooth(1.),
63 if (slotwidth==0) fSize = 1;
64 else fSize = (tend-t0)/slotwidth;
65 fPArray = new AliRelAlignerKalman* [fSize];
66 if (fPArray) for (Int_t i=0;i<fSize;i++){fPArray[i]=NULL;}//fill with zeros
70 //______________________________________________________________________________
71 AliRelAlignerKalmanArray::AliRelAlignerKalmanArray( const AliRelAlignerKalmanArray& in):
72 TNamed(in.GetName(), in.GetTitle()),
74 fTimebinWidth(in.fTimebinWidth),
76 fOutRejSigmaOnMerge(in.fOutRejSigmaOnMerge),
77 fOutRejSigmaOnSmooth(in.fOutRejSigmaOnSmooth),
81 fAlignerTemplate = in.fAlignerTemplate;
82 fPArray = new AliRelAlignerKalman* [fSize];
83 if (!fPArray) {fSize=0;return;} //if fail
84 for (Int_t i=0;i<fSize;i++)
86 if (in.fPArray[i]) fPArray[i]=new AliRelAlignerKalman(*(in.fPArray[i]));
91 //______________________________________________________________________________
92 AliRelAlignerKalmanArray::~AliRelAlignerKalmanArray()
99 //______________________________________________________________________________
100 void AliRelAlignerKalmanArray::SetupArray(Int_t t0, Int_t tend, Int_t slotwidth)
102 //setup array - clears old content
105 fTimebinWidth=slotwidth;
107 if (slotwidth==0) tmpsize = 1;
108 else tmpsize = (tend-t0)/slotwidth;
112 fPArray=new AliRelAlignerKalman* [tmpsize];
113 if (fPArray) fSize=tmpsize;
116 for (Int_t i=0;i<fSize;i++){fPArray[i]=NULL;}//fill with zeros
119 //______________________________________________________________________________
120 AliRelAlignerKalman* AliRelAlignerKalmanArray::GetAlignerTemplate()
122 return fAlignerTemplate;
125 //______________________________________________________________________________
126 Long64_t AliRelAlignerKalmanArray::Merge( TCollection* list )
128 //Merge all the arrays
129 //tlihe merge is vertical, meaning matching entries in tree are merged
131 AliRelAlignerKalmanArray *arrayFromList;
134 while ( (arrayFromList = dynamic_cast<AliRelAlignerKalmanArray*>(next())) )
136 if (fT0 != arrayFromList->fT0) continue;
137 if (fTimebinWidth != arrayFromList->fTimebinWidth) continue;
138 if (fSize != arrayFromList->fSize) continue;
140 for (Int_t i=0; i<GetSize(); i++)
142 AliRelAlignerKalman* a1 = fPArray[i];
143 AliRelAlignerKalman* a2 = arrayFromList->fPArray[i];
146 a1->SetRejectOutliers(kFALSE);
147 a1->SetOutRejSigma(fOutRejSigmaOnMerge); a1->Merge(a2);
150 if (!a1 && a2) fPArray[i] = new AliRelAlignerKalman(*a2);
156 //______________________________________________________________________________
157 Int_t AliRelAlignerKalmanArray::Timebin( UInt_t timestamp ) const
159 //calculate binnumber for given timestamp
160 if (fTimebinWidth==0) return 0;
161 Int_t slot = (timestamp-fT0)/fTimebinWidth; //it's all integers!
165 //______________________________________________________________________________
166 AliRelAlignerKalman* AliRelAlignerKalmanArray::GetAligner(UInt_t ts)
168 //get the aligner for specified timestamp
169 Int_t tb = Timebin(ts);
170 if (tb<0) return NULL;
171 if (tb>=fSize) return NULL;
172 if (!fPArray) return NULL;
175 fPArray[tb] = new AliRelAlignerKalman( *fAlignerTemplate );
176 fPArray[tb]->SetTimeStamp(fT0+tb*fTimebinWidth);
181 //______________________________________________________________________________
182 AliRelAlignerKalman* AliRelAlignerKalmanArray::GetAligner(AliESDEvent* event)
184 //get the aligner for this event and set relevant info
185 AliRelAlignerKalman* a = GetAligner(event->GetTimeStamp());
186 if (a) a->SetRunNumber(event->GetRunNumber());
187 if (a) a->SetMagField(event->GetMagneticField());
191 //______________________________________________________________________________
192 AliRelAlignerKalmanArray& AliRelAlignerKalmanArray::operator=(const AliRelAlignerKalmanArray& in)
194 //assignment operator
197 //if sizes different, delete curent and make a new one with new size
200 fPArray = new AliRelAlignerKalman* [in.fSize];
203 fOutRejSigmaOnMerge=in.fOutRejSigmaOnMerge;
204 fOutRejSigmaOnSmooth=in.fOutRejSigmaOnSmooth;
206 if (!fPArray) fSize=0;
207 else fSize = in.fSize;
208 fTimebinWidth = in.fTimebinWidth;
210 for (Int_t i=0;i<fSize;i++)
212 if (in.fPArray[i]) fPArray[i] = new AliRelAlignerKalman(*(in.fPArray[i]));
213 else fPArray[i]=NULL;
218 //______________________________________________________________________________
219 void AliRelAlignerKalmanArray::ClearContents()
221 //clear contents of array
222 for (Int_t i=0;i<fSize;i++)
224 if (fPArray[i]) delete fPArray[i];
228 //______________________________________________________________________________
229 AliRelAlignerKalman* AliRelAlignerKalmanArray::At( Int_t i ) const
231 //mimic TObjArray::At( Int_t i )
232 if (i>=fSize) {printf("AliRelAlignerKalmanArray::At index %i out of bounds, size=%i\n",i,fSize); return NULL;}
233 if (i<0) return NULL;
237 //______________________________________________________________________________
238 AliRelAlignerKalman* AliRelAlignerKalmanArray::operator[](Int_t i) const
240 //mimic TObjArray::operator[](Int_t)
241 if (i>=fSize) {printf("AliRelAlignerKalmanArray::operator[] index %i out of bounds, size=%i\n",i,fSize); return NULL;}
242 if (i<0) return NULL;
246 //______________________________________________________________________________
247 AliRelAlignerKalman*& AliRelAlignerKalmanArray::operator[](Int_t i)
249 //mimic TObjArray::operator[](Int_t) can be used as lvalue
250 if (i>=fSize||i<0) {Error("operator[]", "index %i out of bounds, size=%i\n",i,fSize); return fPArray[0];}
254 //______________________________________________________________________________
255 AliRelAlignerKalman* AliRelAlignerKalmanArray::Last() const
257 //return aligner in last filled slot
258 if (fSize==0) return NULL;
259 return fPArray[fSize-1];
262 //______________________________________________________________________________
263 void AliRelAlignerKalmanArray::Print(Option_t* option) const
266 TString optionStr(option);
267 printf( "%s: t0: %i, tend: %i, width: %i, size: %i, entries: %i\n",
269 fT0, (fT0+(fSize)*fTimebinWidth), fTimebinWidth,
270 fSize, GetEntries() );
271 if (optionStr.Contains("a"))
272 for (Int_t i=0; i<fSize; i++)
274 AliRelAlignerKalman* al = fPArray[i];
280 //______________________________________________________________________________
281 Int_t AliRelAlignerKalmanArray::GetEntries() const
283 //get number of filled slots
284 if (!fPArray) return 0;
286 for (Int_t i=0; i<fSize; i++)
288 if (fPArray[i]) entries++;
293 //______________________________________________________________________________
294 void AliRelAlignerKalmanArray::FillTree( TTree* tree ) const
296 AliRelAlignerKalman* al = NULL;
297 tree->Branch("aligner","AliRelAlignerKalman",&al);
298 //fill a tree with filled slots
299 for (Int_t i=0; i<fSize; i++)
302 if (al) tree->Fill();
306 //______________________________________________________________________________
307 TGraphErrors* AliRelAlignerKalmanArray::MakeGraph(Int_t iparam) const
309 //return a graph for the iparam-th parameter
310 if (iparam>8 || iparam<0)
312 printf("wrong parameter number. must be from 0-8");
316 TVectorD vx(GetEntries());
317 TVectorD vy(GetEntries());
318 TVectorD vex(GetEntries());
319 TVectorD vey(GetEntries());
321 for (Int_t i=0; i<fSize; i++)
323 AliRelAlignerKalman* al = fPArray[i];
325 vx(entry) = al->GetTimeStamp();
326 vy(entry) = al->GetStateArr()[iparam];
327 TMatrixDSym* cm = al->GetStateCov();
328 vey(entry) = TMath::Sqrt((*cm)(iparam,iparam));
332 TGraphErrors* graph = new TGraphErrors(vx,vy,vex,vey);
338 graphtitle="rotation \\psi";
339 graphtitley="\\psi [rad]";
342 graphtitle="rotation \\theta";
343 graphtitley="\\theta [rad]";
346 graphtitle="rotation \\phi";
347 graphtitley="\\phi [rad]";
350 graphtitle="shift x";
351 graphtitley="x [cm]";
354 graphtitle="shift y";
355 graphtitley="y [cm]";
358 graphtitle="shift z";
359 graphtitley="z [cm]";
362 graphtitle="TPC vd correction";
363 graphtitley="correction factor []";
366 graphtitle="TPC t0 correction";
367 graphtitley="t0 correction [\\micros]";
370 graphtitle="TPC dv/dy";
371 graphtitley="dv/dy [cm/\\micros/m]";
374 graph->SetTitle(graphtitle);
375 TAxis* xas = graph->GetXaxis();
376 TAxis* yas = graph->GetYaxis();
377 xas->SetTitle("time");
378 xas->SetTimeDisplay(1);
379 yas->SetTitle(graphtitley);
383 //______________________________________________________________________________
384 AliRelAlignerKalmanArray* AliRelAlignerKalmanArray::MakeSmoothArray() const
386 //return a smoothed version of the data
387 AliRelAlignerKalmanArray* outputarr = new AliRelAlignerKalmanArray(fT0,
388 fT0+fSize*fTimebinWidth,fTimebinWidth);
390 AliRelAlignerKalman* tmpaligner = outputarr->GetAlignerTemplate();
391 tmpaligner->SetOutRejSigma(fOutRejSigmaOnSmooth);
392 //copy the first filled slot
394 while (!fPArray[n]) {n++;}
395 if (n==fSize) return NULL;
396 *tmpaligner = *fPArray[n];
397 if (fPArray[n]->GetNUpdates()>10)
398 (*outputarr)[n] = new AliRelAlignerKalman(*(fPArray[n]));
399 //for the rest of slots use merge
400 for (Int_t i=n+1;i<fSize;i++)
402 if (!fPArray[i]) continue;
403 PropagateToTime(tmpaligner, fPArray[i]->GetTimeStamp());
404 if (tmpaligner->Merge(fPArray[i]))
405 (*outputarr)[i] = new AliRelAlignerKalman(*tmpaligner);
407 (*outputarr)[i] = new AliRelAlignerKalman(*(fPArray[i]));
410 tmpaligner->Reset(); //clean up
415 //______________________________________________________________________________
416 void AliRelAlignerKalmanArray::PropagateToTime(AliRelAlignerKalman* al, UInt_t timestamp ) const
418 //propagate an aligner in time
419 TMatrixDSym* cov = al->GetStateCov();
420 TMatrixDSym corr(TMatrixDSym::kZero,*cov);
421 UInt_t dt = (timestamp>al->GetTimeStamp())?
422 timestamp-al->GetTimeStamp():al->GetTimeStamp()-timestamp;
423 //the propagation matrix
424 //to be added to the covariance matrix of kalman filter
425 corr(6,6) = dt*1e-8; //vdrift