]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAlignmentTracks.cxx
New version of the alignment framework (for details see offline week 6-10 Mar 2006)
[u/mrichter/AliRoot.git] / STEER / AliAlignmentTracks.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 //-----------------------------------------------------------------
17 //   Implementation of the alignment steering class
18 //   It provides an access to the track space points
19 //   written along the esd tracks. The class enables
20 //   the user to plug any track fitter (deriving from
21 //   AliTrackFitter class) and minimization fo the
22 //   track residual sums (deriving from the AliTrackResiduals).
23 //-----------------------------------------------------------------
24
25 #include <TChain.h>
26 #include <TFile.h>
27
28 #include "AliAlignmentTracks.h"
29 #include "AliTrackPointArray.h"
30 #include "AliAlignObjAngles.h"
31 #include "AliTrackFitterRieman.h"
32 #include "AliTrackResidualsChi2.h"
33 #include "AliESD.h"
34 #include "AliLog.h"
35
36 ClassImp(AliAlignmentTracks)
37
38 //______________________________________________________________________________
39 AliAlignmentTracks::AliAlignmentTracks():
40   fESDChain(0),
41   fPointsFilename("AliTrackPoints.root"),
42   fPointsFile(0),
43   fPointsTree(0),
44   fLastIndex(0),
45   fArrayIndex(0),
46   fIsIndexBuilt(kFALSE),
47   fMisalignObjs(0),
48   fTrackFitter(0),
49   fMinimizer(0)
50 {
51   // Default constructor
52   InitIndex();
53   InitAlignObjs();
54 }
55
56 //______________________________________________________________________________
57 AliAlignmentTracks::AliAlignmentTracks(TChain *esdchain):
58   fESDChain(esdchain),
59   fPointsFilename("AliTrackPoints.root"),
60   fPointsFile(0),
61   fPointsTree(0),
62   fLastIndex(0),
63   fArrayIndex(0),
64   fIsIndexBuilt(kFALSE),
65   fMisalignObjs(0),
66   fTrackFitter(0),
67   fMinimizer(0)
68 {
69   // Constructor in the case
70   // the user provides an already
71   // built TChain with ESD trees
72   InitIndex();
73   InitAlignObjs();
74 }
75
76
77 //______________________________________________________________________________
78 AliAlignmentTracks::AliAlignmentTracks(const char *esdfilename, const char *esdtreename):
79   fPointsFilename("AliTrackPoints.root"),
80   fPointsFile(0),
81   fPointsTree(0),
82   fLastIndex(0),
83   fArrayIndex(0),
84   fIsIndexBuilt(kFALSE),
85   fMisalignObjs(0),
86   fTrackFitter(0),
87   fMinimizer(0)
88 {
89   // Constructor in the case
90   // the user provides a single ESD file
91   // or a directory containing ESD files
92   fESDChain = new TChain(esdtreename);
93   fESDChain->Add(esdfilename);
94
95   InitIndex();
96   InitAlignObjs();
97 }
98
99 //______________________________________________________________________________
100 AliAlignmentTracks::AliAlignmentTracks(const AliAlignmentTracks &alignment):
101   TObject(alignment)
102 {
103   // Copy constructor
104   // not implemented
105   AliWarning("Copy constructor not implemented!");
106 }
107
108 //______________________________________________________________________________
109 AliAlignmentTracks& AliAlignmentTracks::operator= (const AliAlignmentTracks& alignment)
110 {
111   // Asignment operator
112   // not implemented
113   if(this==&alignment) return *this;
114
115   AliWarning("Asignment operator not implemented!");
116
117   ((TObject *)this)->operator=(alignment);
118
119   return *this;
120 }
121
122 //______________________________________________________________________________
123 AliAlignmentTracks::~AliAlignmentTracks()
124 {
125   // Destructor
126   if (fESDChain) delete fESDChain;
127
128   DeleteIndex();
129   DeleteAlignObjs();
130
131   delete fTrackFitter;
132   delete fMinimizer;
133
134   if (fPointsFile) fPointsFile->Close();
135 }
136
137 //______________________________________________________________________________
138 void AliAlignmentTracks::AddESD(TChain *esdchain)
139 {
140   // Add a chain with ESD files
141   if (fESDChain)
142     fESDChain->Add(esdchain);
143   else
144     fESDChain = esdchain;
145 }
146
147 //______________________________________________________________________________
148 void AliAlignmentTracks::AddESD(const char *esdfilename, const char *esdtreename)
149 {
150   // Add a single file or
151   // a directory to the chain
152   // with the ESD files
153   if (fESDChain)
154     fESDChain->AddFile(esdfilename,TChain::kBigNumber,esdtreename);
155   else {
156     fESDChain = new TChain(esdtreename);
157     fESDChain->Add(esdfilename);
158   }
159 }
160
161 //______________________________________________________________________________
162 void AliAlignmentTracks::ProcessESD()
163 {
164   // Analyzes and filters ESD tracks
165   // Stores the selected track space points
166   // into the output file
167
168   if (!fESDChain) return;
169
170   AliESD *esd = 0;
171   fESDChain->SetBranchAddress("ESD",&esd);
172
173   // Open the output file
174   if (fPointsFilename.Data() == "") {
175     AliWarning("Incorrect output filename!");
176     return;
177   }
178
179   TFile *pointsFile = TFile::Open(fPointsFilename,"RECREATE");
180   if (!pointsFile || !pointsFile->IsOpen()) {
181     AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
182     return;
183   }
184
185   TTree *pointsTree = new TTree("spTree", "Tree with track space point arrays");
186   AliTrackPointArray *array = 0;
187   pointsTree->Branch("SP","AliTrackPointArray", &array);
188
189   Int_t ievent = 0;
190   while (fESDChain->GetEntry(ievent++)) {
191     if (!esd) break;
192     Int_t ntracks = esd->GetNumberOfTracks();
193     for (Int_t itrack=0; itrack < ntracks; itrack++) {
194       AliESDtrack * track = esd->GetTrack(itrack);
195       if (!track) continue;
196  
197      //  UInt_t status = AliESDtrack::kITSpid; 
198 //       status|=AliESDtrack::kTPCpid; 
199 //       status|=AliESDtrack::kTRDpid; 
200 //       if ((track->GetStatus() & status) != status) continue;
201
202       if (track->GetP() < 0.5) continue;
203
204       array = track->GetTrackPointArray();
205       pointsTree->Fill();
206     }
207   }
208
209   if (!pointsTree->Write()) {
210     AliWarning("Can't write the tree with track point arrays!");
211     return;
212   }
213
214   pointsFile->Close();
215 }
216
217 //______________________________________________________________________________
218 void AliAlignmentTracks::ProcessESD(TSelector *selector)
219 {
220   AliWarning(Form("ESD processing based on selector is not yet implemented (%p) !",selector));
221 }
222
223 //______________________________________________________________________________
224 void AliAlignmentTracks::BuildIndex()
225 {
226   // Build index of points tree entries
227   // Used for access based on the volume IDs
228   if (fIsIndexBuilt) return;
229
230   fIsIndexBuilt = kTRUE;
231
232   TFile *fPointsFile = TFile::Open(fPointsFilename);
233   if (!fPointsFile || !fPointsFile->IsOpen()) {
234     AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
235     return;
236   }
237   
238   //  AliTrackPointArray* array = new AliTrackPointArray;
239   AliTrackPointArray* array = 0;
240   fPointsTree = (TTree*) fPointsFile->Get("spTree");
241   if (!fPointsTree) {
242     AliWarning("No pointsTree found!");
243     return;
244   }
245   fPointsTree->SetBranchAddress("SP", &array);
246
247   Int_t nArrays = fPointsTree->GetEntries();
248   for (Int_t iArray = 0; iArray < nArrays; iArray++)
249     {
250       fPointsTree->GetEvent(iArray);
251       if (!array) continue;
252       for (Int_t ipoint = 0; ipoint < array->GetNPoints(); ipoint++) {
253         UShort_t volId = array->GetVolumeID()[ipoint];
254         Int_t modId;
255         Int_t layerId = AliAlignObj::VolUIDToLayer(volId,modId)
256                       - AliAlignObj::kFirstLayer;
257         if (!fArrayIndex[layerId][modId]) {
258           //first entry for this volume
259           fArrayIndex[layerId][modId] = new TArrayI(1000);
260         }
261         else {
262           Int_t size = fArrayIndex[layerId][modId]->GetSize();
263           // If needed allocate new size
264           if (fLastIndex[layerId][modId] >= size)
265             fArrayIndex[layerId][modId]->Set(size + 1000);
266         }
267
268         // Check if the index is already filled
269         Bool_t fillIndex = kTRUE;
270         if (fLastIndex[layerId][modId] != 0) {
271           if ((*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]-1] == iArray)
272             fillIndex = kFALSE;
273         }
274         // Fill the index array and store last filled index
275         if (fillIndex) {
276           (*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]] = iArray;
277           fLastIndex[layerId][modId]++;
278         }
279       }
280     }
281
282 }
283
284 //______________________________________________________________________________
285 void AliAlignmentTracks::InitIndex()
286 {
287   // Initialize the index arrays
288   Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
289   fLastIndex = new Int_t*[nLayers];
290   fArrayIndex = new TArrayI**[nLayers];
291   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
292     fLastIndex[iLayer] = new Int_t[AliAlignObj::LayerSize(iLayer)];
293     fArrayIndex[iLayer] = new TArrayI*[AliAlignObj::LayerSize(iLayer)];
294     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
295       fLastIndex[iLayer][iModule] = 0;
296       fArrayIndex[iLayer][iModule] = 0;
297     }
298   }
299 }
300
301 //______________________________________________________________________________
302 void AliAlignmentTracks::ResetIndex()
303 {
304   // Reset the value of the last filled index
305   // Do not realocate memory
306
307   fIsIndexBuilt = kFALSE;
308   
309   for (Int_t iLayer = 0; iLayer < AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer; iLayer++) {
310     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
311       fLastIndex[iLayer][iModule] = 0;
312     }
313   }
314 }
315
316 //______________________________________________________________________________
317 void AliAlignmentTracks::DeleteIndex()
318 {
319   // Delete the index arrays
320   // Called by the destructor
321   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
322     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
323       if (fArrayIndex[iLayer][iModule]) {
324         delete fArrayIndex[iLayer][iModule];
325         fArrayIndex[iLayer][iModule] = 0;
326       }
327     }
328     delete [] fLastIndex[iLayer];
329     delete [] fArrayIndex[iLayer];
330   }
331   delete [] fLastIndex;
332   delete [] fArrayIndex;
333 }
334
335 //______________________________________________________________________________
336 Bool_t AliAlignmentTracks::ReadAlignObjs(const char *alignObjFileName, const char* arrayName)
337 {
338   // Read alignment object from a file
339   // To be replaced by a call to CDB
340   AliWarning(Form("Method not yet implemented (%s in %s) !",arrayName,alignObjFileName));
341
342   return kFALSE;
343 }
344
345 //______________________________________________________________________________
346 void AliAlignmentTracks::InitAlignObjs()
347 {
348   // Initialize the alignment objects array
349   Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
350   fAlignObjs = new AliAlignObj**[nLayers];
351   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
352     fAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
353     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
354       UShort_t volid = AliAlignObj::LayerToVolUID(iLayer+ AliAlignObj::kFirstLayer,iModule);
355       fAlignObjs[iLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0);
356     }
357   }
358 }
359
360 //______________________________________________________________________________
361 void AliAlignmentTracks::ResetAlignObjs()
362 {
363   // Reset the alignment objects array
364   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
365     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
366       fAlignObjs[iLayer][iModule]->SetPars(0,0,0,0,0,0);
367   }
368 }
369
370 //______________________________________________________________________________
371 void AliAlignmentTracks::DeleteAlignObjs()
372 {
373   // Delete the alignment objects array
374   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
375     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
376       if (fAlignObjs[iLayer][iModule])
377         delete fAlignObjs[iLayer][iModule];
378     delete [] fAlignObjs[iLayer];
379   }
380   delete [] fAlignObjs;
381   fAlignObjs = 0;
382 }
383
384 void AliAlignmentTracks::AlignDetector(AliAlignObj::ELayerID firstLayer,
385                                        AliAlignObj::ELayerID lastLayer,
386                                        AliAlignObj::ELayerID layerRangeMin,
387                                        AliAlignObj::ELayerID layerRangeMax,
388                                        Int_t iterations)
389 {
390   // Align detector volumes within
391   // a given layer range
392   // (could be whole detector).
393   // Tracks are fitted only within
394   // the range defined by the user.
395   Int_t nModules = 0;
396   for (Int_t iLayer = firstLayer; iLayer < lastLayer; iLayer++)
397     nModules += AliAlignObj::LayerSize(iLayer - AliAlignObj::kFirstLayer);
398   TArrayI volIds(nModules);
399
400   Int_t modnum = 0;
401   for (Int_t iLayer = firstLayer; iLayer < lastLayer; iLayer++) {
402     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer - AliAlignObj::kFirstLayer); iModule++) {
403       UShort_t volId = AliAlignObj::LayerToVolUID(iLayer,iModule);
404       volIds.AddAt(volId,modnum);
405       modnum++;
406     }
407   }
408
409   while (iterations > 0) {
410     AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
411     iterations--;
412   }
413 }
414
415 //______________________________________________________________________________
416 void AliAlignmentTracks::AlignLayer(AliAlignObj::ELayerID layer,
417                                     AliAlignObj::ELayerID layerRangeMin,
418                                     AliAlignObj::ELayerID layerRangeMax,
419                                     Int_t iterations)
420 {
421   // Align detector volumes within
422   // a given layer.
423   // Tracks are fitted only within
424   // the range defined by the user.
425   Int_t nModules = AliAlignObj::LayerSize(layer - AliAlignObj::kFirstLayer);
426   TArrayI volIds(nModules);
427   for (Int_t iModule = 0; iModule < nModules; iModule++) {
428     UShort_t volId = AliAlignObj::LayerToVolUID(layer,iModule);
429     volIds.AddAt(volId,iModule);
430   }
431
432   while (iterations > 0) {
433     AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
434     iterations--;
435   }
436 }
437
438 //______________________________________________________________________________
439 void AliAlignmentTracks::AlignVolume(UShort_t volId, UShort_t volIdFit,
440                                      Int_t iterations)
441 {
442   // Align single detector volume to
443   // another volume.
444   // Tracks are fitted only within
445   // the second volume.
446   TArrayI volIds(1);
447   volIds.AddAt(volId,0);
448   TArrayI volIdsFit(1);
449   volIdsFit.AddAt(volIdFit,0);
450
451   while (iterations > 0) {
452     AlignVolumes(&volIds,&volIdsFit);
453     iterations--;
454   }
455 }
456
457 //______________________________________________________________________________
458 void AliAlignmentTracks::AlignVolumes(const TArrayI *volids, const TArrayI *volidsfit,
459                                      AliAlignObj::ELayerID layerRangeMin,
460                                      AliAlignObj::ELayerID layerRangeMax,
461                                      Int_t iterations)
462 {
463   // Align a set of detector volumes.
464   // Tracks are fitted only within
465   // the range defined by the user
466   // (by layerRangeMin and layerRangeMax)
467   // or within the set of volidsfit
468   // Repeat the procedure 'iterations' times
469
470   Int_t nVolIds = volids->GetSize();
471   if (nVolIds == 0) {
472     AliError("Volume IDs array is empty!");
473     return;
474   }
475
476   // Load only the tracks with at least one
477   // space point in the set of volume (volids)
478   BuildIndex();
479   AliTrackPointArray **points;
480   // Start the iterations
481   while (iterations > 0) {
482     Int_t nArrays = LoadPoints(volids, points);
483     if (nArrays == 0) return;
484
485     AliTrackResiduals *minimizer = CreateMinimizer();
486     minimizer->SetNTracks(nArrays);
487     minimizer->InitAlignObj();
488     AliTrackFitter *fitter = CreateFitter();
489     for (Int_t iArray = 0; iArray < nArrays; iArray++) {
490       fitter->SetTrackPointArray(points[iArray], kFALSE);
491       fitter->Fit(volids,volidsfit,layerRangeMin,layerRangeMax);
492       AliTrackPointArray *pVolId,*pTrack;
493       fitter->GetTrackResiduals(pVolId,pTrack);
494       minimizer->AddTrackPointArrays(pVolId,pTrack);
495     }
496     minimizer->Minimize();
497
498     // Update the alignment object(s)
499     for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
500       UShort_t volid = (*volids)[iVolId];
501       Int_t iModule;
502       AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
503       AliAlignObj *alignObj = fAlignObjs[iLayer-AliAlignObj::kFirstLayer][iModule];
504       *alignObj *= *minimizer->GetAlignObj();
505       alignObj->Print("");
506     }
507
508     UnloadPoints(nArrays, points);
509     
510     iterations--;
511   }
512 }
513   
514 //______________________________________________________________________________
515 Int_t AliAlignmentTracks::LoadPoints(const TArrayI *volids, AliTrackPointArray** &points)
516 {
517   // Load track point arrays with at least
518   // one space point in a given set of detector
519   // volumes (array volids).
520   // Use the already created tree index for
521   // fast access.
522
523   if (!fPointsTree) {
524     AliError("Tree with the space point arrays not initialized!");
525     points = 0;
526     return 0;
527   }
528
529   Int_t nVolIds = volids->GetSize();
530   if (nVolIds == 0) {
531     AliError("Volume IDs array is empty!");
532     points = 0;
533     return 0;
534   }
535
536   Int_t nArrays = 0;
537   for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
538     UShort_t volid = (*volids)[iVolId];
539     Int_t iModule;
540     AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
541
542     // In case of empty index
543     if (fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule] == 0) {
544       AliWarning(Form("There are no space-points belonging to the volume which is to be aligned (Volume ID =%d)!",volid));
545       continue;
546     }
547     nArrays += fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
548   }
549
550   if (nArrays == 0) {
551     AliError("There are no space-points belonging to all of the volumes which are to be aligned!");
552     points = 0;
553     return 0;
554   }
555
556   AliTrackPointArray* array = 0;
557   fPointsTree->SetBranchAddress("SP", &array);
558
559   // Allocate the pointer to the space-point arrays
560   points = new AliTrackPointArray*[nArrays];
561
562   // Init the array used to flag already loaded tree entries
563   Bool_t *indexUsed = new Bool_t[fPointsTree->GetEntries()];
564   for (Int_t i = 0; i < fPointsTree->GetEntries(); i++)
565     indexUsed[i] = kFALSE;
566
567   // Start the loop over the volume ids
568   Int_t iArray = 0;
569   for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
570     UShort_t volid = (*volids)[iVolId];
571     Int_t iModule;
572     AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
573
574     Int_t nArraysId = fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
575     TArrayI *index = fArrayIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
576     AliTrackPoint p;
577
578     for (Int_t iArrayId = 0; iArrayId < nArraysId; iArrayId++) {
579
580       // Get tree entry
581       Int_t entry = (*index)[iArrayId];
582       if (indexUsed[entry] == kTRUE) continue;
583       fPointsTree->GetEvent(entry);
584       if (!array) {
585         AliWarning("Wrong space point array index!");
586         continue;
587       }
588       indexUsed[entry] = kTRUE;
589
590       // Get the space-point array
591       Int_t nPoints = array->GetNPoints();
592       points[iArray] = new AliTrackPointArray(nPoints);
593       for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
594         array->GetPoint(p,iPoint);
595         Int_t modnum;
596         AliAlignObj::ELayerID layer = AliAlignObj::VolUIDToLayer(p.GetVolumeID(),modnum);
597
598         // Misalignment is introduced here
599         // Switch it off in case of real
600         // alignment job!
601         if (fMisalignObjs) {
602           AliAlignObj *misalignObj = fMisalignObjs[layer-AliAlignObj::kFirstLayer][modnum];
603           if (misalignObj)
604             misalignObj->Transform(p);
605         }
606         // End of misalignment
607
608         AliAlignObj *alignObj = fAlignObjs[layer-AliAlignObj::kFirstLayer][modnum];
609         alignObj->Transform(p);
610         points[iArray]->AddPoint(iPoint,&p);
611       }
612       iArray++;
613     }
614   }
615
616
617   delete [] indexUsed;
618
619   return nArrays;
620 }
621
622 //______________________________________________________________________________
623 void AliAlignmentTracks::UnloadPoints(Int_t n, AliTrackPointArray **points)
624 {
625   // Unload track point arrays for a given
626   // detector volume
627   for (Int_t iArray = 0; iArray < n; iArray++)
628     delete points[iArray];
629   delete [] points;
630 }
631
632 //______________________________________________________________________________
633 AliTrackFitter *AliAlignmentTracks::CreateFitter()
634 {
635   // Check if the user has already supplied
636   // a track fitter object.
637   // If not, create a default one.
638   if (!fTrackFitter)
639     fTrackFitter = new AliTrackFitterRieman;
640
641   return fTrackFitter;
642 }
643
644 //______________________________________________________________________________
645 AliTrackResiduals *AliAlignmentTracks::CreateMinimizer()
646 {
647   // Check if the user has already supplied
648   // a track residuals minimizer object.
649   // If not, create a default one.
650   if (!fMinimizer)
651     fMinimizer = new AliTrackResidualsChi2;
652
653   return fMinimizer;
654 }
655
656 //______________________________________________________________________________
657 Bool_t AliAlignmentTracks::Misalign(const char *misalignObjFileName, const char* arrayName)
658 {
659   // The method reads from a file a set of AliAlignObj which are
660   // then used to apply misalignments directly on the track
661   // space-points. The method is supposed to be used only for
662   // fast development and debugging of the alignment algorithms.
663   // Be careful not to use it in the case of 'real' alignment
664   // scenario since it will bias the results.
665
666   // Initialize the misalignment objects array
667   Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
668   fMisalignObjs = new AliAlignObj**[nLayers];
669   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
670     fMisalignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
671     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
672       fMisalignObjs[iLayer][iModule] = 0x0;
673   }
674
675   // Open the misliagnment file and load the array with
676   // misalignment objects
677   TFile* inFile = TFile::Open(misalignObjFileName,"READ");
678   if (!inFile || !inFile->IsOpen()) {
679     AliError(Form("Could not open misalignment file %s !",misalignObjFileName));
680     return kFALSE;
681   }
682
683   TClonesArray* array = ((TClonesArray*) inFile->Get(arrayName));
684   if (!array) {
685     AliError(Form("Could not find misalignment array %s in the file %s !",arrayName,misalignObjFileName));
686     inFile->Close();
687     return kFALSE;
688   }
689   inFile->Close();
690
691   // Store the misalignment objects for further usage  
692   Int_t nObjs = array->GetEntriesFast();
693   AliAlignObj::ELayerID layerId; // volume layer
694   Int_t modId; // volume ID inside the layer
695   for(Int_t i=0; i<nObjs; i++)
696     {
697       AliAlignObj* alObj = (AliAlignObj*)array->UncheckedAt(i);
698       alObj->GetVolUID(layerId,modId);
699       fMisalignObjs[layerId-AliAlignObj::kFirstLayer][modId] = alObj;
700     }
701   return kTRUE;
702 }