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 //-----------------------------------------------------------------
29 #include "AliAlignmentTracks.h"
30 #include "AliTrackPointArray.h"
31 #include "AliAlignObjParams.h"
32 #include "AliTrackFitterRieman.h"
33 #include "AliTrackResidualsChi2.h"
34 #include "AliESDEvent.h"
37 ClassImp(AliAlignmentTracks)
39 //______________________________________________________________________________
40 AliAlignmentTracks::AliAlignmentTracks():
42 fPointsFilename("AliTrackPoints.root"),
47 fIsIndexBuilt(kFALSE),
54 // Default constructor
59 //______________________________________________________________________________
60 AliAlignmentTracks::AliAlignmentTracks(TChain *esdchain):
62 fPointsFilename("AliTrackPoints.root"),
67 fIsIndexBuilt(kFALSE),
74 // Constructor in the case
75 // the user provides an already
76 // built TChain with ESD trees
82 //______________________________________________________________________________
83 AliAlignmentTracks::AliAlignmentTracks(const char *esdfilename, const char *esdtreename):
84 fESDChain(new TChain(esdtreename)),
85 fPointsFilename("AliTrackPoints.root"),
90 fIsIndexBuilt(kFALSE),
97 // Constructor in the case
98 // the user provides a single ESD file
99 // or a directory containing ESD files
100 fESDChain->Add(esdfilename);
107 //______________________________________________________________________________
108 AliAlignmentTracks::~AliAlignmentTracks()
111 if (fESDChain) delete fESDChain;
119 if (fPointsFile) fPointsFile->Close();
122 //______________________________________________________________________________
123 void AliAlignmentTracks::AddESD(TChain *esdchain)
125 // Add a chain with ESD files
127 fESDChain->Add(esdchain);
129 fESDChain = esdchain;
132 //______________________________________________________________________________
133 void AliAlignmentTracks::AddESD(const char *esdfilename, const char *esdtreename)
135 // Add a single file or
136 // a directory to the chain
137 // with the ESD files
139 fESDChain->AddFile(esdfilename,TChain::kBigNumber,esdtreename);
141 fESDChain = new TChain(esdtreename);
142 fESDChain->Add(esdfilename);
146 //________________________________________________________________________
147 void AliAlignmentTracks::ProcessESD(Bool_t onlyITS,
150 Float_t minAngleWrtITSModulePlanes,
151 Float_t minMom,Float_t maxMom,
152 Float_t minAbsSinPhi,Float_t maxAbsSinPhi,
153 Float_t minSinTheta,Float_t maxSinTheta)
155 // Analyzes and filters ESD tracks
156 // Stores the selected track space points
157 // into the output file
159 if (!fESDChain) return;
161 AliESDEvent *esd = new AliESDEvent();
162 esd->ReadFromTree(fESDChain);
163 AliESDfriend *esdf = 0;
164 fESDChain->SetBranchStatus("ESDfriend*",1);
165 fESDChain->SetBranchAddress("ESDfriend.",&esdf);
167 // Open the output file
168 if (fPointsFilename.Data() == "") {
169 AliWarning("Incorrect output filename!");
173 TFile *pointsFile = TFile::Open(fPointsFilename,"RECREATE");
174 if (!pointsFile || !pointsFile->IsOpen()) {
175 AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
179 TTree *pointsTree = new TTree("spTree", "Tree with track space point arrays");
180 const AliTrackPointArray *array = 0;
181 AliTrackPointArray *array2 = 0;
182 if(onlyITS) { // only ITS AliTrackPoints
183 pointsTree->Branch("SP","AliTrackPointArray", &array2);
185 pointsTree->Branch("SP","AliTrackPointArray", &array);
189 while (fESDChain->GetEntry(ievent++)) {
192 esd->SetESDfriend(esdf); //Attach the friend to the ESD
194 Int_t ntracks = esd->GetNumberOfTracks();
195 for (Int_t itrack=0; itrack < ntracks; itrack++) {
196 AliESDtrack * track = esd->GetTrack(itrack);
197 if (!track) continue;
199 if(track->GetNcls(0) < minITSpts) continue;
201 if(track->GetP()<minMom || track->GetP()>maxMom) continue;
202 Float_t abssinphi = TMath::Abs(TMath::Sin(track->GetAlpha()+TMath::ASin(track->GetSnp())));
203 if(abssinphi<minAbsSinPhi || abssinphi>maxAbsSinPhi) continue;
204 Float_t sintheta = TMath::Sin(0.5*TMath::Pi()-TMath::ATan(track->GetTgl()));
205 if(sintheta<minSinTheta || sintheta>maxSinTheta) continue;
209 array = track->GetTrackPointArray();
212 array2 = new AliTrackPointArray(track->GetNcls(0));
213 Bool_t smallAngleWrtITSModulePlanes=kFALSE;
214 Int_t ipt,volId,modId,layerId;
216 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
217 array->GetPoint(point,ipt);
218 volId = point.GetVolumeID();
219 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
221 array2->AddPoint(jpt,&point);
224 // check minAngleWrtITSModulePlanes
226 Double_t p[3]; track->GetDirection(p);
227 TVector3 pvec(p[0],p[1],p[2]);
228 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
229 TVector3 normvec(rot[1],-rot[0],0.);
230 Double_t angle = pvec.Angle(normvec);
231 if(angle>0.5*TMath::Pi()) angle = TMath::Pi()-angle;
232 angle = 0.5*TMath::Pi()-angle;
233 if(angle<minAngleWrtITSModulePlanes) smallAngleWrtITSModulePlanes=kTRUE;
236 if(smallAngleWrtITSModulePlanes) continue;
243 if (!pointsTree->Write()) {
244 AliWarning("Can't write the tree with track point arrays!");
253 //_____________________________________________________________________________
254 void AliAlignmentTracks::ProcessESDCosmics(Bool_t onlyITS,
255 Int_t minITSpts,Float_t maxMatchingAngle,
257 Float_t minAngleWrtITSModulePlanes,
258 Float_t minMom,Float_t maxMom,
259 Float_t minAbsSinPhi,Float_t maxAbsSinPhi,
260 Float_t minSinTheta,Float_t maxSinTheta)
262 // Analyzes and filters ESD tracks
263 // Merges inward and outward tracks in one single track
264 // Stores the selected track space points
265 // into the output file
267 if (!fESDChain) return;
269 AliESDEvent *esd = new AliESDEvent();
270 esd->ReadFromTree(fESDChain);
271 AliESDfriend *esdf = 0;
272 fESDChain->SetBranchStatus("ESDfriend*",1);
273 fESDChain->SetBranchAddress("ESDfriend.",&esdf);
275 // Open the output file
276 if (fPointsFilename.Data() == "") {
277 AliWarning("Incorrect output filename!");
281 TFile *pointsFile = TFile::Open(fPointsFilename,"RECREATE");
282 if (!pointsFile || !pointsFile->IsOpen()) {
283 AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
287 TTree *pointsTree = new TTree("spTree", "Tree with track space point arrays");
288 const AliTrackPointArray *array = 0;
289 AliTrackPointArray *array2 = 0;
290 pointsTree->Branch("SP","AliTrackPointArray", &array2);
293 while (fESDChain->GetEntry(ievent++)) {
296 esd->SetESDfriend(esdf); //Attach the friend to the ESD
298 Int_t ntracks = esd->GetNumberOfTracks();
299 if(ntracks<2) continue;
300 Int_t *goodtracksArray = new Int_t[ntracks];
301 Float_t *phiArray = new Float_t[ntracks];
302 Float_t *thetaArray = new Float_t[ntracks];
304 for (Int_t itrack=0; itrack < ntracks; itrack++) {
305 AliESDtrack * track = esd->GetTrack(itrack);
306 if (!track) continue;
308 if(track->GetNcls(0) < minITSpts) continue;
309 Float_t phi = track->GetAlpha()+TMath::ASin(track->GetSnp());
310 Float_t theta = 0.5*TMath::Pi()-TMath::ATan(track->GetTgl());
312 if(track->GetP()<minMom || track->GetP()>maxMom) continue;
313 Float_t abssinphi = TMath::Abs(TMath::Sin(phi));
314 if(abssinphi<minAbsSinPhi || abssinphi>maxAbsSinPhi) continue;
315 Float_t sintheta = TMath::Sin(theta);
316 if(sintheta<minSinTheta || sintheta>maxSinTheta) continue;
318 goodtracksArray[ngt]=itrack;
320 thetaArray[ngt]=theta;
325 delete [] goodtracksArray; goodtracksArray=0;
326 delete [] phiArray; phiArray=0;
327 delete [] thetaArray; thetaArray=0;
331 // check matching of the two tracks from the muon
332 Float_t min = 10000000.;
333 Int_t good1 = -1, good2 = -1;
334 for(Int_t itr1=0; itr1<ngt-1; itr1++) {
335 for(Int_t itr2=itr1+1; itr2<ngt; itr2++) {
336 Float_t deltatheta = TMath::Abs(TMath::Pi()-thetaArray[itr1]-thetaArray[itr2]);
337 if(deltatheta>maxMatchingAngle) continue;
338 Float_t deltaphi = TMath::Abs(TMath::Abs(phiArray[itr1]-phiArray[itr2])-TMath::Pi());
339 if(deltaphi>maxMatchingAngle) continue;
340 //printf("%f %f %f %f\n",deltaphi,deltatheta,thetaArray[itr1],thetaArray[itr2]);
341 if(deltatheta+deltaphi<min) {
342 min=deltatheta+deltaphi;
343 good1 = goodtracksArray[itr1];
344 good2 = goodtracksArray[itr2];
349 delete [] goodtracksArray; goodtracksArray=0;
350 delete [] phiArray; phiArray=0;
351 delete [] thetaArray; thetaArray=0;
353 if(good1<0) continue;
355 AliESDtrack * track1 = esd->GetTrack(good1);
356 AliESDtrack * track2 = esd->GetTrack(good2);
360 ntotpts = track1->GetNcls(0)+track2->GetNcls(0);
362 ntotpts = track1->GetTrackPointArray()->GetNPoints()+
363 track2->GetTrackPointArray()->GetNPoints();
365 array2 = new AliTrackPointArray(ntotpts);
367 Int_t ipt,volId,modId,layerId;
369 Bool_t smallAngleWrtITSModulePlanes=kFALSE;
370 array = track1->GetTrackPointArray();
371 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
372 array->GetPoint(point,ipt);
374 volId = point.GetVolumeID();
375 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
376 if(layerId>6) continue;
377 // check minAngleWrtITSModulePlanes
379 Double_t p[3]; track1->GetDirection(p);
380 TVector3 pvec(p[0],p[1],p[2]);
381 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
382 TVector3 normvec(rot[1],-rot[0],0.);
383 Double_t angle = pvec.Angle(normvec);
384 if(angle>0.5*TMath::Pi()) angle = TMath::Pi()-angle;
385 angle = 0.5*TMath::Pi()-angle;
386 if(angle<minAngleWrtITSModulePlanes) smallAngleWrtITSModulePlanes=kTRUE;
389 array2->AddPoint(jpt,&point);
392 array = track2->GetTrackPointArray();
393 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
394 array->GetPoint(point,ipt);
396 volId = point.GetVolumeID();
397 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
398 if(layerId>6) continue;
399 // check minAngleWrtITSModulePlanes
401 Double_t p[3]; track2->GetDirection(p);
402 TVector3 pvec(p[0],p[1],p[2]);
403 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
404 TVector3 normvec(rot[1],-rot[0],0.);
405 Double_t angle = pvec.Angle(normvec);
406 if(angle>0.5*TMath::Pi()) angle = TMath::Pi()-angle;
407 angle = 0.5*TMath::Pi()-angle;
408 if(angle<minAngleWrtITSModulePlanes) smallAngleWrtITSModulePlanes=kTRUE;
411 array2->AddPoint(jpt,&point);
415 if(smallAngleWrtITSModulePlanes) continue;
419 if (!pointsTree->Write()) {
420 AliWarning("Can't write the tree with track point arrays!");
428 //______________________________________________________________________________
429 void AliAlignmentTracks::ProcessESD(TSelector *selector)
431 AliWarning(Form("ESD processing based on selector is not yet implemented (%p) !",selector));
434 //______________________________________________________________________________
435 void AliAlignmentTracks::BuildIndex()
437 // Build index of points tree entries
438 // Used for access based on the volume IDs
439 if (fIsIndexBuilt) return;
441 fIsIndexBuilt = kTRUE;
443 // Dummy object is created in order
444 // to initialize the volume paths
445 AliAlignObjParams alobj;
447 fPointsFile = TFile::Open(fPointsFilename);
448 if (!fPointsFile || !fPointsFile->IsOpen()) {
449 AliWarning(Form("Can't open %s !",fPointsFilename.Data()));
453 // AliTrackPointArray* array = new AliTrackPointArray;
454 AliTrackPointArray* array = 0;
455 fPointsTree = (TTree*) fPointsFile->Get("spTree");
457 AliWarning("No pointsTree found!");
460 fPointsTree->SetBranchAddress("SP", &array);
462 Int_t nArrays = (Int_t)fPointsTree->GetEntries();
463 for (Int_t iArray = 0; iArray < nArrays; iArray++)
465 fPointsTree->GetEvent(iArray);
466 if (!array) continue;
467 for (Int_t ipoint = 0; ipoint < array->GetNPoints(); ipoint++) {
468 UShort_t volId = array->GetVolumeID()[ipoint];
469 // check if the volId is valid
470 if (!AliGeomManager::SymName(volId)) {
471 AliError(Form("The volume id %d has no default volume name !",
476 Int_t layerId = AliGeomManager::VolUIDToLayer(volId,modId)
477 - AliGeomManager::kFirstLayer;
478 if (!fArrayIndex[layerId][modId]) {
479 //first entry for this volume
480 fArrayIndex[layerId][modId] = new TArrayI(1000);
483 Int_t size = fArrayIndex[layerId][modId]->GetSize();
484 // If needed allocate new size
485 if (fLastIndex[layerId][modId] >= size)
486 fArrayIndex[layerId][modId]->Set(size + 1000);
489 // Check if the index is already filled
490 Bool_t fillIndex = kTRUE;
491 if (fLastIndex[layerId][modId] != 0) {
492 if ((*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]-1] == iArray)
495 // Fill the index array and store last filled index
497 (*fArrayIndex[layerId][modId])[fLastIndex[layerId][modId]] = iArray;
498 fLastIndex[layerId][modId]++;
505 //______________________________________________________________________________
506 void AliAlignmentTracks::InitIndex()
508 // Initialize the index arrays
509 Int_t nLayers = AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer;
510 fLastIndex = new Int_t*[nLayers];
511 fArrayIndex = new TArrayI**[nLayers];
512 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
513 fLastIndex[iLayer] = new Int_t[AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer)];
514 fArrayIndex[iLayer] = new TArrayI*[AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer)];
515 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++) {
516 fLastIndex[iLayer][iModule] = 0;
517 fArrayIndex[iLayer][iModule] = 0;
522 //______________________________________________________________________________
523 void AliAlignmentTracks::ResetIndex()
525 // Reset the value of the last filled index
526 // Do not realocate memory
528 fIsIndexBuilt = kFALSE;
530 for (Int_t iLayer = 0; iLayer < AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer; iLayer++) {
531 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++) {
532 fLastIndex[iLayer][iModule] = 0;
537 //______________________________________________________________________________
538 void AliAlignmentTracks::DeleteIndex()
540 // Delete the index arrays
541 // Called by the destructor
542 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
543 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++) {
544 if (fArrayIndex[iLayer][iModule]) {
545 delete fArrayIndex[iLayer][iModule];
546 fArrayIndex[iLayer][iModule] = 0;
549 delete [] fLastIndex[iLayer];
550 delete [] fArrayIndex[iLayer];
552 delete [] fLastIndex;
553 delete [] fArrayIndex;
556 //______________________________________________________________________________
557 Bool_t AliAlignmentTracks::ReadAlignObjs(const char *alignObjFileName, const char* arrayName)
559 // Read alignment object from a file
560 // To be replaced by a call to CDB
561 AliWarning(Form("Method not yet implemented (%s in %s) !",arrayName,alignObjFileName));
566 //______________________________________________________________________________
567 void AliAlignmentTracks::InitAlignObjs()
569 // Initialize the alignment objects array
570 Int_t nLayers = AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer;
571 fAlignObjs = new AliAlignObj**[nLayers];
572 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
573 fAlignObjs[iLayer] = new AliAlignObj*[AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer)];
574 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++) {
575 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer+ AliGeomManager::kFirstLayer,iModule);
576 fAlignObjs[iLayer][iModule] = new AliAlignObjParams(AliGeomManager::SymName(volid),volid,0,0,0,0,0,0,kTRUE);
581 //______________________________________________________________________________
582 void AliAlignmentTracks::ResetAlignObjs()
584 // Reset the alignment objects array
585 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
586 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++)
587 fAlignObjs[iLayer][iModule]->SetPars(0,0,0,0,0,0);
591 //______________________________________________________________________________
592 void AliAlignmentTracks::DeleteAlignObjs()
594 // Delete the alignment objects array
595 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
596 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++)
597 if (fAlignObjs[iLayer][iModule])
598 delete fAlignObjs[iLayer][iModule];
599 delete [] fAlignObjs[iLayer];
601 delete [] fAlignObjs;
605 void AliAlignmentTracks::AlignDetector(AliGeomManager::ELayerID firstLayer,
606 AliGeomManager::ELayerID lastLayer,
607 AliGeomManager::ELayerID layerRangeMin,
608 AliGeomManager::ELayerID layerRangeMax,
611 // Align detector volumes within
612 // a given layer range
613 // (could be whole detector).
614 // Tracks are fitted only within
615 // the range defined by the user.
617 for (Int_t iLayer = firstLayer; iLayer <= lastLayer; iLayer++)
618 nModules += AliGeomManager::LayerSize(iLayer);
619 TArrayI volIds(nModules);
622 for (Int_t iLayer = firstLayer; iLayer <= lastLayer; iLayer++) {
623 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer); iModule++) {
624 UShort_t volId = AliGeomManager::LayerToVolUID(iLayer,iModule);
625 volIds.AddAt(volId,modnum);
630 while (iterations > 0) {
631 AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
636 //______________________________________________________________________________
637 void AliAlignmentTracks::AlignLayer(AliGeomManager::ELayerID layer,
638 AliGeomManager::ELayerID layerRangeMin,
639 AliGeomManager::ELayerID layerRangeMax,
642 // Align detector volumes within
644 // Tracks are fitted only within
645 // the range defined by the user.
646 Int_t nModules = AliGeomManager::LayerSize(layer);
647 TArrayI volIds(nModules);
648 for (Int_t iModule = 0; iModule < nModules; iModule++) {
649 UShort_t volId = AliGeomManager::LayerToVolUID(layer,iModule);
650 volIds.AddAt(volId,iModule);
653 while (iterations > 0) {
654 AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
659 //______________________________________________________________________________
660 void AliAlignmentTracks::AlignVolume(UShort_t volId, UShort_t volIdFit,
663 // Align single detector volume to
665 // Tracks are fitted only within
666 // the second volume.
668 volIds.AddAt(volId,0);
669 TArrayI volIdsFit(1);
670 volIdsFit.AddAt(volIdFit,0);
672 while (iterations > 0) {
673 AlignVolumes(&volIds,&volIdsFit);
678 //______________________________________________________________________________
679 void AliAlignmentTracks::AlignVolumes(const TArrayI *volids, const TArrayI *volidsfit,
680 AliGeomManager::ELayerID layerRangeMin,
681 AliGeomManager::ELayerID layerRangeMax,
684 // Align a set of detector volumes.
685 // Tracks are fitted only within
686 // the range defined by the user
687 // (by layerRangeMin and layerRangeMax)
688 // or within the set of volidsfit
689 // Repeat the procedure 'iterations' times
691 Int_t nVolIds = volids->GetSize();
693 AliError("Volume IDs array is empty!");
697 // Load only the tracks with at least one
698 // space point in the set of volume (volids)
700 AliTrackPointArray **points;
701 // Start the iterations
702 while (iterations > 0) {
703 Int_t nArrays = LoadPoints(volids, points);
704 if (nArrays == 0) return;
706 AliTrackResiduals *minimizer = CreateMinimizer();
707 minimizer->SetNTracks(nArrays);
708 minimizer->InitAlignObj();
709 AliTrackFitter *fitter = CreateFitter();
710 for (Int_t iArray = 0; iArray < nArrays; iArray++) {
711 if (!points[iArray]) continue;
712 fitter->SetTrackPointArray(points[iArray], kFALSE);
713 if (fitter->Fit(volids,volidsfit,layerRangeMin,layerRangeMax) == kFALSE) continue;
714 AliTrackPointArray *pVolId,*pTrack;
715 fitter->GetTrackResiduals(pVolId,pTrack);
716 minimizer->AddTrackPointArrays(pVolId,pTrack);
718 minimizer->Minimize();
720 // Update the alignment object(s)
721 if (fDoUpdate) for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
722 UShort_t volid = (*volids)[iVolId];
724 AliGeomManager::ELayerID iLayer = AliGeomManager::VolUIDToLayer(volid,iModule);
725 AliAlignObj *alignObj = fAlignObjs[iLayer-AliGeomManager::kFirstLayer][iModule];
726 *alignObj *= *minimizer->GetAlignObj();
730 UnloadPoints(nArrays, points);
736 //______________________________________________________________________________
737 Int_t AliAlignmentTracks::LoadPoints(const TArrayI *volids, AliTrackPointArray** &points)
739 // Load track point arrays with at least
740 // one space point in a given set of detector
741 // volumes (array volids).
742 // Use the already created tree index for
746 AliError("Tree with the space point arrays not initialized!");
751 Int_t nVolIds = volids->GetSize();
753 AliError("Volume IDs array is empty!");
759 for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
760 UShort_t volid = (*volids)[iVolId];
762 AliGeomManager::ELayerID iLayer = AliGeomManager::VolUIDToLayer(volid,iModule);
764 // In case of empty index
765 if (fLastIndex[iLayer-AliGeomManager::kFirstLayer][iModule] == 0) {
766 AliWarning(Form("There are no space-points belonging to the volume which is to be aligned (Volume ID =%d)!",volid));
769 nArrays += fLastIndex[iLayer-AliGeomManager::kFirstLayer][iModule];
773 AliError("There are no space-points belonging to all of the volumes which are to be aligned!");
778 AliTrackPointArray* array = 0;
779 fPointsTree->SetBranchAddress("SP", &array);
781 // Allocate the pointer to the space-point arrays
782 points = new AliTrackPointArray*[nArrays];
783 for (Int_t i = 0; i < nArrays; i++) points[i] = 0x0;
785 // Init the array used to flag already loaded tree entries
786 Bool_t *indexUsed = new Bool_t[(UInt_t)fPointsTree->GetEntries()];
787 for (Int_t i = 0; i < fPointsTree->GetEntries(); i++)
788 indexUsed[i] = kFALSE;
790 // Start the loop over the volume ids
792 for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
793 UShort_t volid = (*volids)[iVolId];
795 AliGeomManager::ELayerID iLayer = AliGeomManager::VolUIDToLayer(volid,iModule);
797 Int_t nArraysId = fLastIndex[iLayer-AliGeomManager::kFirstLayer][iModule];
798 TArrayI *index = fArrayIndex[iLayer-AliGeomManager::kFirstLayer][iModule];
801 for (Int_t iArrayId = 0; iArrayId < nArraysId; iArrayId++) {
804 Int_t entry = (*index)[iArrayId];
805 if (indexUsed[entry] == kTRUE) continue;
806 fPointsTree->GetEvent(entry);
808 AliWarning("Wrong space point array index!");
811 indexUsed[entry] = kTRUE;
813 // Get the space-point array
814 Int_t nPoints = array->GetNPoints();
815 points[iArray] = new AliTrackPointArray(nPoints);
816 for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
817 array->GetPoint(p,iPoint);
819 AliGeomManager::ELayerID layer = AliGeomManager::VolUIDToLayer(p.GetVolumeID(),modnum);
820 // check if the layer id is valid
821 if ((layer < AliGeomManager::kFirstLayer) ||
822 (layer >= AliGeomManager::kLastLayer)) {
823 AliError(Form("Layer index is invalid: %d (%d -> %d) !",
824 layer,AliGeomManager::kFirstLayer,AliGeomManager::kLastLayer-1));
827 if ((modnum >= AliGeomManager::LayerSize(layer)) ||
829 AliError(Form("Module number inside layer %d is invalid: %d (0 -> %d)",
830 layer,modnum,AliGeomManager::LayerSize(layer)));
834 // Misalignment is introduced here
835 // Switch it off in case of real
838 AliAlignObj *misalignObj = fMisalignObjs[layer-AliGeomManager::kFirstLayer][modnum];
840 misalignObj->Transform(p);
842 // End of misalignment
844 AliAlignObj *alignObj = fAlignObjs[layer-AliGeomManager::kFirstLayer][modnum];
845 alignObj->Transform(p);
846 points[iArray]->AddPoint(iPoint,&p);
858 //______________________________________________________________________________
859 void AliAlignmentTracks::UnloadPoints(Int_t n, AliTrackPointArray **points)
861 // Unload track point arrays for a given
863 for (Int_t iArray = 0; iArray < n; iArray++)
864 delete points[iArray];
868 //______________________________________________________________________________
869 AliTrackFitter *AliAlignmentTracks::CreateFitter()
871 // Check if the user has already supplied
872 // a track fitter object.
873 // If not, create a default one.
875 fTrackFitter = new AliTrackFitterRieman;
880 //______________________________________________________________________________
881 AliTrackResiduals *AliAlignmentTracks::CreateMinimizer()
883 // Check if the user has already supplied
884 // a track residuals minimizer object.
885 // If not, create a default one.
887 fMinimizer = new AliTrackResidualsChi2;
892 //______________________________________________________________________________
893 Bool_t AliAlignmentTracks::Misalign(const char *misalignObjFileName, const char* arrayName)
895 // The method reads from a file a set of AliAlignObj which are
896 // then used to apply misalignments directly on the track
897 // space-points. The method is supposed to be used only for
898 // fast development and debugging of the alignment algorithms.
899 // Be careful not to use it in the case of 'real' alignment
900 // scenario since it will bias the results.
902 // Initialize the misalignment objects array
903 Int_t nLayers = AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer;
904 fMisalignObjs = new AliAlignObj**[nLayers];
905 for (Int_t iLayer = 0; iLayer < (AliGeomManager::kLastLayer - AliGeomManager::kFirstLayer); iLayer++) {
906 fMisalignObjs[iLayer] = new AliAlignObj*[AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer)];
907 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(iLayer + AliGeomManager::kFirstLayer); iModule++)
908 fMisalignObjs[iLayer][iModule] = 0x0;
911 // Open the misliagnment file and load the array with
912 // misalignment objects
913 TFile* inFile = TFile::Open(misalignObjFileName,"READ");
914 if (!inFile || !inFile->IsOpen()) {
915 AliError(Form("Could not open misalignment file %s !",misalignObjFileName));
919 TClonesArray* array = ((TClonesArray*) inFile->Get(arrayName));
921 AliError(Form("Could not find misalignment array %s in the file %s !",arrayName,misalignObjFileName));
927 // Store the misalignment objects for further usage
928 Int_t nObjs = array->GetEntriesFast();
929 AliGeomManager::ELayerID layerId; // volume layer
930 Int_t modId; // volume ID inside the layer
931 for(Int_t i=0; i<nObjs; i++)
933 AliAlignObj* alObj = (AliAlignObj*)array->UncheckedAt(i);
934 alObj->GetVolUID(layerId,modId);
935 fMisalignObjs[layerId-AliGeomManager::kFirstLayer][modId] = alObj;