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 //-----------------------------------------------------------------
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 //-----------------------------------------------------------------
27 #include "AliAlignmentTracks.h"
28 #include "AliTrackPointArray.h"
29 #include "AliAlignObjAngles.h"
30 #include "AliTrackFitterRieman.h"
31 #include "AliTrackResidualsChi2.h"
35 ClassImp(AliAlignmentTracks)
37 //______________________________________________________________________________
38 AliAlignmentTracks::AliAlignmentTracks():
40 fPointsFilename("AliTrackPoints.root"),
45 fIsIndexBuilt(kFALSE),
49 // Default constructor
54 //______________________________________________________________________________
55 AliAlignmentTracks::AliAlignmentTracks(TChain *esdchain):
57 fPointsFilename("AliTrackPoints.root"),
62 fIsIndexBuilt(kFALSE),
66 // Constructor in the case
67 // the user provides an already
68 // built TChain with ESD trees
74 //______________________________________________________________________________
75 AliAlignmentTracks::AliAlignmentTracks(const char *esdfilename, const char *esdtreename):
76 fPointsFilename("AliTrackPoints.root"),
81 fIsIndexBuilt(kFALSE),
85 // Constructor in the case
86 // the user provides a single ESD file
87 // or a directory containing ESD files
88 fESDChain = new TChain(esdtreename);
89 fESDChain->Add(esdfilename);
95 //______________________________________________________________________________
96 AliAlignmentTracks::AliAlignmentTracks(const AliAlignmentTracks &alignment):
101 AliWarning("Copy constructor not implemented!");
104 //______________________________________________________________________________
105 AliAlignmentTracks& AliAlignmentTracks::operator= (const AliAlignmentTracks& alignment)
107 // Asignment operator
109 if(this==&alignment) return *this;
111 AliWarning("Asignment operator not implemented!");
113 ((TObject *)this)->operator=(alignment);
118 //______________________________________________________________________________
119 AliAlignmentTracks::~AliAlignmentTracks()
122 if (fESDChain) delete fESDChain;
130 if (fPointsFile) fPointsFile->Close();
133 //______________________________________________________________________________
134 void AliAlignmentTracks::AddESD(TChain *esdchain)
136 // Add a chain with ESD files
138 fESDChain->Add(esdchain);
140 fESDChain = esdchain;
143 //______________________________________________________________________________
144 void AliAlignmentTracks::AddESD(const char *esdfilename, const char *esdtreename)
146 // Add a single file or
147 // a directory to the chain
148 // with the ESD files
150 fESDChain->AddFile(esdfilename,TChain::kBigNumber,esdtreename);
152 fESDChain = new TChain(esdtreename);
153 fESDChain->Add(esdfilename);
157 //______________________________________________________________________________
158 void AliAlignmentTracks::ProcessESD()
160 // Analyzes and filters ESD tracks
161 // Stores the selected track space points
162 // into the output file
164 if (!fESDChain) return;
167 fESDChain->SetBranchAddress("ESD",&esd);
169 // Open the output file
170 if (fPointsFilename.Data() == "") {
171 AliWarning("Incorrect output filename!");
175 TFile *pointsFile = TFile::Open(fPointsFilename,"RECREATE");
176 if (!pointsFile || !pointsFile->IsOpen()) {
177 AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
181 TTree *pointsTree = new TTree("spTree", "Tree with track space point arrays");
182 AliTrackPointArray *array = 0;
183 pointsTree->Branch("SP","AliTrackPointArray", &array);
186 while (fESDChain->GetEntry(ievent++)) {
188 Int_t ntracks = esd->GetNumberOfTracks();
189 for (Int_t itrack=0; itrack < ntracks; itrack++) {
190 AliESDtrack * track = esd->GetTrack(itrack);
191 if (!track) continue;
193 UInt_t status = AliESDtrack::kITSpid;
194 status|=AliESDtrack::kTPCpid;
195 status|=AliESDtrack::kTRDpid;
196 if ((track->GetStatus() & status) != status) continue;
198 if (track->GetP() < 0.5) continue;
200 array = track->GetTrackPointArray();
205 if (!pointsTree->Write()) {
206 AliWarning("Can't write the tree with track point arrays!");
213 //______________________________________________________________________________
214 void AliAlignmentTracks::ProcessESD(TSelector *selector)
216 AliWarning(Form("ESD processing based on selector is not yet implemented (%p) !",selector));
219 //______________________________________________________________________________
220 void AliAlignmentTracks::BuildIndex()
222 // Build index of points tree entries
223 // Used for access based on the volume IDs
227 fIsIndexBuilt = kTRUE;
229 TFile *fPointsFile = TFile::Open(fPointsFilename);
230 if (!fPointsFile || !fPointsFile->IsOpen()) {
231 AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
235 // AliTrackPointArray* array = new AliTrackPointArray;
236 AliTrackPointArray* array = 0;
237 TTree* pointsTree = (TTree*) fPointsFile->Get("spTree");
239 AliWarning("No pointsTree found!");
242 pointsTree->SetBranchAddress("SP", &array);
244 Int_t nArrays = pointsTree->GetEntries();
245 for (Int_t iArray = 0; iArray < nArrays; iArray++)
247 pointsTree->GetEvent(iArray);
248 if (!array) continue;
249 for (Int_t ipoint = 0; ipoint < array->GetNPoints(); ipoint++) {
250 UShort_t volId = array->GetVolumeID()[ipoint];
252 Int_t layerId = AliAlignObj::VolUIDToLayer(volId,modId)
253 - AliAlignObj::kFirstLayer;
254 if (!fArrayIndex[layerId][modId]) {
255 //first entry for this volume
256 fArrayIndex[layerId][modId] = new TArrayI(1000);
259 Int_t size = fArrayIndex[layerId][modId]->GetSize();
260 // If needed allocate new size
261 if (fLastIndex[layerId][modId] >= size)
262 fArrayIndex[layerId][modId]->Set(size + 1000);
265 // Check if the index is already filled
266 Bool_t fillIndex = kTRUE;
267 if (fLastIndex[layerId][modId] != 0) {
268 if ((*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]-1] == iArray)
271 // Fill the index array and store last filled index
273 (*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]] = iArray;
274 fLastIndex[layerId][modId]++;
281 // //______________________________________________________________________________
282 // void AliAlignmentTracks::BuildIndexLayer(AliAlignObj::ELayerID layer)
286 // //______________________________________________________________________________
287 // void AliAlignmentTracks::BuildIndexVolume(UShort_t volid)
291 //______________________________________________________________________________
292 void AliAlignmentTracks::InitIndex()
294 // Initialize the index arrays
295 Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
296 fLastIndex = new Int_t*[nLayers];
297 fArrayIndex = new TArrayI**[nLayers];
298 for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
299 fLastIndex[iLayer] = new Int_t[AliAlignObj::LayerSize(iLayer)];
300 fArrayIndex[iLayer] = new TArrayI*[AliAlignObj::LayerSize(iLayer)];
301 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
302 fLastIndex[iLayer][iModule] = 0;
303 fArrayIndex[iLayer][iModule] = 0;
308 //______________________________________________________________________________
309 void AliAlignmentTracks::ResetIndex()
311 // Reset the value of the last filled index
312 // Do not realocate memory
313 for (Int_t iLayer = AliAlignObj::kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) {
314 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
315 fLastIndex[iLayer][iModule] = 0;
320 //______________________________________________________________________________
321 void AliAlignmentTracks::DeleteIndex()
323 // Delete the index arrays
324 // Called by the destructor
325 for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
326 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
327 if (fArrayIndex[iLayer][iModule]) {
328 delete fArrayIndex[iLayer][iModule];
329 fArrayIndex[iLayer][iModule] = 0;
332 delete [] fLastIndex[iLayer];
333 delete [] fArrayIndex[iLayer];
335 delete [] fLastIndex;
336 delete [] fArrayIndex;
339 //______________________________________________________________________________
340 Bool_t AliAlignmentTracks::ReadAlignObjs(const char *alignobjfilename)
342 // Read alignment object from a file
343 // To be replaced by a call to CDB
344 AliWarning(Form("Method not yet implemented (%s) !",alignobjfilename));
349 //______________________________________________________________________________
350 void AliAlignmentTracks::InitAlignObjs()
352 // Initialize the alignment objects array
353 Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
354 fAlignObjs = new AliAlignObj**[nLayers];
355 for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
356 fAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
357 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
358 fAlignObjs[iLayer][iModule] = new AliAlignObjAngles;
362 //______________________________________________________________________________
363 void AliAlignmentTracks::ResetAlignObjs()
365 // Reset the alignment objects array
366 for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
367 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
368 fAlignObjs[iLayer][iModule]->SetPars(0,0,0,0,0,0);
372 //______________________________________________________________________________
373 void AliAlignmentTracks::DeleteAlignObjs()
375 // Delete the alignment objects array
376 for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
377 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
378 if (fAlignObjs[iLayer][iModule])
379 delete fAlignObjs[iLayer][iModule];
380 delete [] fAlignObjs[iLayer];
382 delete [] fAlignObjs;
385 //______________________________________________________________________________
386 void AliAlignmentTracks::Align(Int_t iterations)
388 // This method is just an example
389 // how one can user AlignLayer and
390 // AlignVolume methods to construct
391 // a custom alignment procedure
392 while (iterations > 0) {
394 AlignLayer(AliAlignObj::kTPC1);
395 AlignLayer(AliAlignObj::kSSD2);
396 AlignLayer(AliAlignObj::kSSD1);
397 AlignLayer(AliAlignObj::kSDD2);
398 AlignLayer(AliAlignObj::kSDD1);
399 AlignLayer(AliAlignObj::kSPD2);
400 AlignLayer(AliAlignObj::kSPD1);
402 AlignLayer(AliAlignObj::kSPD2);
403 AlignLayer(AliAlignObj::kSDD1);
404 AlignLayer(AliAlignObj::kSDD2);
405 AlignLayer(AliAlignObj::kSSD1);
406 AlignLayer(AliAlignObj::kSSD2);
407 AlignLayer(AliAlignObj::kTPC1);
408 AlignLayer(AliAlignObj::kTPC2);
409 AlignLayer(AliAlignObj::kTRD1);
410 AlignLayer(AliAlignObj::kTRD2);
411 AlignLayer(AliAlignObj::kTRD3);
412 AlignLayer(AliAlignObj::kTRD4);
413 AlignLayer(AliAlignObj::kTRD5);
414 AlignLayer(AliAlignObj::kTRD6);
415 AlignLayer(AliAlignObj::kTOF);
417 AlignLayer(AliAlignObj::kTRD6);
418 AlignLayer(AliAlignObj::kTRD5);
419 AlignLayer(AliAlignObj::kTRD4);
420 AlignLayer(AliAlignObj::kTRD3);
421 AlignLayer(AliAlignObj::kTRD2);
422 AlignLayer(AliAlignObj::kTRD1);
423 AlignLayer(AliAlignObj::kTPC2);
427 //______________________________________________________________________________
428 void AliAlignmentTracks::AlignLayer(AliAlignObj::ELayerID layer,
429 AliAlignObj::ELayerID layerRangeMin,
430 AliAlignObj::ELayerID layerRangeMax,
433 // Align detector volumes within
435 // Tracks are fitted only within
436 // the range defined by the user.
437 while (iterations > 0) {
438 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(layer); iModule++) {
439 UShort_t volId = AliAlignObj::LayerToVolUID(layer,iModule);
440 AlignVolume(volId,layerRangeMin,layerRangeMax);
446 //______________________________________________________________________________
447 void AliAlignmentTracks::AlignVolume(UShort_t volid,
448 AliAlignObj::ELayerID layerRangeMin,
449 AliAlignObj::ELayerID layerRangeMax)
451 // Align a single detector volume.
452 // Tracks are fitted only within
453 // the range defined by the user.
455 // First take the alignment object to be updated
457 AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
458 AliAlignObj *alignObj = fAlignObjs[iLayer][iModule];
460 // Then load only the tracks with at least one
461 // space point in the volume (volid)
463 AliTrackPointArray **points;
464 Int_t nArrays = LoadPoints(volid, points);
465 if (nArrays == 0) return;
467 AliTrackResiduals *minimizer = CreateMinimizer();
468 minimizer->SetNTracks(nArrays);
469 minimizer->SetAlignObj(alignObj);
470 AliTrackFitter *fitter = CreateFitter();
471 for (Int_t iArray = 0; iArray < nArrays; iArray++) {
472 fitter->SetTrackPointArray(points[iArray], kFALSE);
473 AliTrackPointArray *pVolId = 0, *pTrack = 0;
474 fitter->Fit(volid,pVolId,pTrack,layerRangeMin,layerRangeMax);
475 minimizer->AddTrackPointArrays(pVolId,pTrack);
477 minimizer->Minimize();
479 UnloadPoints(nArrays, points);
482 //______________________________________________________________________________
483 Int_t AliAlignmentTracks::LoadPoints(UShort_t volid, AliTrackPointArray** &points)
485 // Load track point arrays with at least
486 // one space point in a given detector
488 // Use the already created tree index for
491 AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
492 Int_t nArrays = fLastIndex[iLayer][iModule];
494 // In case of empty index
501 AliWarning("Tree with the space point arrays not initialized!");
506 AliAlignObj *alignObj = fAlignObjs[iLayer][iModule];
508 alignObj->GetMatrix(m);
509 Double_t *rot = m.GetRotationMatrix();
510 Double_t *tr = m.GetTranslation();
512 AliTrackPointArray* array = 0;
513 fPointsTree->SetBranchAddress("SP", &array);
515 points = new AliTrackPointArray*[nArrays];
516 TArrayI *index = fArrayIndex[iLayer][iModule];
518 Float_t xyz[3],cov[6];
520 for (Int_t iArray = 0; iArray < nArrays; iArray++) {
521 fPointsTree->GetEvent((*index)[iArray]);
523 AliWarning("Wrong space point array index!");
526 Int_t nPoints = array->GetNPoints();
527 points[iArray] = new AliTrackPointArray(nPoints);
528 for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
529 array->GetPoint(p,iPoint);
531 for (Int_t i = 0; i < 3; i++)
536 p.SetXYZ(newxyz,cov);
537 points[iArray]->AddPoint(iPoint,&p);
544 //______________________________________________________________________________
545 void AliAlignmentTracks::UnloadPoints(Int_t n, AliTrackPointArray **points)
547 // Unload track point arrays for a given
549 for (Int_t iArray = 0; iArray < n; iArray++)
550 delete points[iArray];
554 //______________________________________________________________________________
555 AliTrackFitter *AliAlignmentTracks::CreateFitter()
557 // Check if the user has already supplied
558 // a track fitter object.
559 // If not, create a default one.
561 fTrackFitter = new AliTrackFitterRieman;
566 //______________________________________________________________________________
567 AliTrackResiduals *AliAlignmentTracks::CreateMinimizer()
569 // Check if the user has already supplied
570 // a track residuals minimizer object.
571 // If not, create a default one.
573 fMinimizer = new AliTrackResidualsChi2;