]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliAlignmentTracks.cxx
Bugfixes and clean-up of alignment object classes. Introduction of so called symbolic...
[u/mrichter/AliRoot.git] / STEER / AliAlignmentTracks.cxx
index 089decebacc35ccb5a9f38970cab5b0d1bd01e8f..140562db9e3ef0b7a42a8a1ceca97d1b1dbf82f8 100644 (file)
@@ -44,8 +44,11 @@ AliAlignmentTracks::AliAlignmentTracks():
   fLastIndex(0),
   fArrayIndex(0),
   fIsIndexBuilt(kFALSE),
+  fAlignObjs(0),
+  fMisalignObjs(0),
   fTrackFitter(0),
-  fMinimizer(0)
+  fMinimizer(0),
+  fDoUpdate(kTRUE)
 {
   // Default constructor
   InitIndex();
@@ -61,8 +64,11 @@ AliAlignmentTracks::AliAlignmentTracks(TChain *esdchain):
   fLastIndex(0),
   fArrayIndex(0),
   fIsIndexBuilt(kFALSE),
+  fAlignObjs(0),
+  fMisalignObjs(0),
   fTrackFitter(0),
-  fMinimizer(0)
+  fMinimizer(0),
+  fDoUpdate(kTRUE)
 {
   // Constructor in the case
   // the user provides an already
@@ -74,47 +80,28 @@ AliAlignmentTracks::AliAlignmentTracks(TChain *esdchain):
 
 //______________________________________________________________________________
 AliAlignmentTracks::AliAlignmentTracks(const char *esdfilename, const char *esdtreename):
+  fESDChain(new TChain(esdtreename)),
   fPointsFilename("AliTrackPoints.root"),
   fPointsFile(0),
   fPointsTree(0),
   fLastIndex(0),
   fArrayIndex(0),
   fIsIndexBuilt(kFALSE),
+  fAlignObjs(0),
+  fMisalignObjs(0),
   fTrackFitter(0),
-  fMinimizer(0)
+  fMinimizer(0),
+  fDoUpdate(kTRUE)
 {
   // Constructor in the case
   // the user provides a single ESD file
   // or a directory containing ESD files
-  fESDChain = new TChain(esdtreename);
   fESDChain->Add(esdfilename);
 
   InitIndex();
   InitAlignObjs();
 }
 
-//______________________________________________________________________________
-AliAlignmentTracks::AliAlignmentTracks(const AliAlignmentTracks &alignment):
-  TObject(alignment)
-{
-  // Copy constructor
-  // not implemented
-  AliWarning("Copy constructor not implemented!");
-}
-
-//______________________________________________________________________________
-AliAlignmentTracks& AliAlignmentTracks::operator= (const AliAlignmentTracks& alignment)
-{
-  // Asignment operator
-  // not implemented
-  if(this==&alignment) return *this;
-
-  AliWarning("Asignment operator not implemented!");
-
-  ((TObject *)this)->operator=(alignment);
-
-  return *this;
-}
 
 //______________________________________________________________________________
 AliAlignmentTracks::~AliAlignmentTracks()
@@ -180,9 +167,8 @@ void AliAlignmentTracks::ProcessESD()
   }
 
   TTree *pointsTree = new TTree("spTree", "Tree with track space point arrays");
-  AliTrackPointArray *array = 0;
+  const AliTrackPointArray *array = 0;
   pointsTree->Branch("SP","AliTrackPointArray", &array);
-
   Int_t ievent = 0;
   while (fESDChain->GetEntry(ievent++)) {
     if (!esd) break;
@@ -191,10 +177,10 @@ void AliAlignmentTracks::ProcessESD()
       AliESDtrack * track = esd->GetTrack(itrack);
       if (!track) continue;
  
-      UInt_t status = AliESDtrack::kITSpid; 
-      status|=AliESDtrack::kTPCpid; 
-      status|=AliESDtrack::kTRDpid; 
-      if ((track->GetStatus() & status) != status) continue;
+     //  UInt_t status = AliESDtrack::kITSpid; 
+//       status|=AliESDtrack::kTPCpid; 
+//       status|=AliESDtrack::kTRDpid; 
+//       if ((track->GetStatus() & status) != status) continue;
 
       if (track->GetP() < 0.5) continue;
 
@@ -222,10 +208,13 @@ void AliAlignmentTracks::BuildIndex()
 {
   // Build index of points tree entries
   // Used for access based on the volume IDs
-  if (fIsIndexBuilt)
-    ResetIndex();
-  else
-    fIsIndexBuilt = kTRUE;
+  if (fIsIndexBuilt) return;
+
+  fIsIndexBuilt = kTRUE;
+
+  // Dummy object is created in order
+  // to initialize the volume paths
+  AliAlignObjAngles alobj;
 
   TFile *fPointsFile = TFile::Open(fPointsFilename);
   if (!fPointsFile || !fPointsFile->IsOpen()) {
@@ -235,20 +224,26 @@ void AliAlignmentTracks::BuildIndex()
   
   //  AliTrackPointArray* array = new AliTrackPointArray;
   AliTrackPointArray* array = 0;
-  TTree* pointsTree = (TTree*) fPointsFile->Get("spTree");
-  if (!pointsTree) {
+  fPointsTree = (TTree*) fPointsFile->Get("spTree");
+  if (!fPointsTree) {
     AliWarning("No pointsTree found!");
     return;
   }
-  pointsTree->SetBranchAddress("SP", &array);
+  fPointsTree->SetBranchAddress("SP", &array);
 
-  Int_t nArrays = pointsTree->GetEntries();
+  Int_t nArrays = fPointsTree->GetEntries();
   for (Int_t iArray = 0; iArray < nArrays; iArray++)
     {
-      pointsTree->GetEvent(iArray);
+      fPointsTree->GetEvent(iArray);
       if (!array) continue;
       for (Int_t ipoint = 0; ipoint < array->GetNPoints(); ipoint++) {
        UShort_t volId = array->GetVolumeID()[ipoint];
+       // check if the volId is valid
+       if (!AliAlignObj::SymName(volId)) {
+         AliError(Form("The volume id %d has no default volume name !",
+                       volId));
+         continue;
+       }
        Int_t modId;
        Int_t layerId = AliAlignObj::VolUIDToLayer(volId,modId)
                      - AliAlignObj::kFirstLayer;
@@ -279,16 +274,6 @@ void AliAlignmentTracks::BuildIndex()
 
 }
 
-// //______________________________________________________________________________
-// void AliAlignmentTracks::BuildIndexLayer(AliAlignObj::ELayerID layer)
-// {
-// }
-
-// //______________________________________________________________________________
-// void AliAlignmentTracks::BuildIndexVolume(UShort_t volid)
-// {
-// }
-
 //______________________________________________________________________________
 void AliAlignmentTracks::InitIndex()
 {
@@ -297,9 +282,9 @@ void AliAlignmentTracks::InitIndex()
   fLastIndex = new Int_t*[nLayers];
   fArrayIndex = new TArrayI**[nLayers];
   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
-    fLastIndex[iLayer] = new Int_t[AliAlignObj::LayerSize(iLayer)];
-    fArrayIndex[iLayer] = new TArrayI*[AliAlignObj::LayerSize(iLayer)];
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
+    fLastIndex[iLayer] = new Int_t[AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer)];
+    fArrayIndex[iLayer] = new TArrayI*[AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer)];
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++) {
       fLastIndex[iLayer][iModule] = 0;
       fArrayIndex[iLayer][iModule] = 0;
     }
@@ -311,8 +296,11 @@ void AliAlignmentTracks::ResetIndex()
 {
   // Reset the value of the last filled index
   // Do not realocate memory
-  for (Int_t iLayer = AliAlignObj::kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) {
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
+
+  fIsIndexBuilt = kFALSE;
+  
+  for (Int_t iLayer = 0; iLayer < AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer; iLayer++) {
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++) {
       fLastIndex[iLayer][iModule] = 0;
     }
   }
@@ -324,7 +312,7 @@ void AliAlignmentTracks::DeleteIndex()
   // Delete the index arrays
   // Called by the destructor
   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++) {
       if (fArrayIndex[iLayer][iModule]) {
        delete fArrayIndex[iLayer][iModule];
        fArrayIndex[iLayer][iModule] = 0;
@@ -338,11 +326,11 @@ void AliAlignmentTracks::DeleteIndex()
 }
 
 //______________________________________________________________________________
-Bool_t AliAlignmentTracks::ReadAlignObjs(const char *alignobjfilename)
+Bool_t AliAlignmentTracks::ReadAlignObjs(const char *alignObjFileName, const char* arrayName)
 {
   // Read alignment object from a file
   // To be replaced by a call to CDB
-  AliWarning(Form("Method not yet implemented (%s) !",alignobjfilename));
+  AliWarning(Form("Method not yet implemented (%s in %s) !",arrayName,alignObjFileName));
 
   return kFALSE;
 }
@@ -354,9 +342,11 @@ void AliAlignmentTracks::InitAlignObjs()
   Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
   fAlignObjs = new AliAlignObj**[nLayers];
   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
-    fAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
-      fAlignObjs[iLayer][iModule] = new AliAlignObjAngles;
+    fAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer)];
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++) {
+      UShort_t volid = AliAlignObj::LayerToVolUID(iLayer+ AliAlignObj::kFirstLayer,iModule);
+      fAlignObjs[iLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
+    }
   }
 }
 
@@ -365,7 +355,7 @@ void AliAlignmentTracks::ResetAlignObjs()
 {
   // Reset the alignment objects array
   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++)
       fAlignObjs[iLayer][iModule]->SetPars(0,0,0,0,0,0);
   }
 }
@@ -375,53 +365,43 @@ void AliAlignmentTracks::DeleteAlignObjs()
 {
   // Delete the alignment objects array
   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++)
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++)
       if (fAlignObjs[iLayer][iModule])
        delete fAlignObjs[iLayer][iModule];
     delete [] fAlignObjs[iLayer];
   }
   delete [] fAlignObjs;
+  fAlignObjs = 0;
 }
 
-//______________________________________________________________________________
-void AliAlignmentTracks::Align(Int_t iterations)
+void AliAlignmentTracks::AlignDetector(AliAlignObj::ELayerID firstLayer,
+                                      AliAlignObj::ELayerID lastLayer,
+                                      AliAlignObj::ELayerID layerRangeMin,
+                                      AliAlignObj::ELayerID layerRangeMax,
+                                      Int_t iterations)
 {
-  // This method is just an example
-  // how one can user AlignLayer and
-  // AlignVolume methods to construct
-  // a custom alignment procedure
+  // Align detector volumes within
+  // a given layer range
+  // (could be whole detector).
+  // Tracks are fitted only within
+  // the range defined by the user.
+  Int_t nModules = 0;
+  for (Int_t iLayer = firstLayer; iLayer < lastLayer; iLayer++)
+    nModules += AliAlignObj::LayerSize(iLayer);
+  TArrayI volIds(nModules);
+
+  Int_t modnum = 0;
+  for (Int_t iLayer = firstLayer; iLayer < lastLayer; iLayer++) {
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
+      UShort_t volId = AliAlignObj::LayerToVolUID(iLayer,iModule);
+      volIds.AddAt(volId,modnum);
+      modnum++;
+    }
+  }
+
   while (iterations > 0) {
-    // First inward pass
-    AlignLayer(AliAlignObj::kTPC1);
-    AlignLayer(AliAlignObj::kSSD2);
-    AlignLayer(AliAlignObj::kSSD1);
-    AlignLayer(AliAlignObj::kSDD2);
-    AlignLayer(AliAlignObj::kSDD1);
-    AlignLayer(AliAlignObj::kSPD2);
-    AlignLayer(AliAlignObj::kSPD1);
-    // Outward pass
-    AlignLayer(AliAlignObj::kSPD2);
-    AlignLayer(AliAlignObj::kSDD1);
-    AlignLayer(AliAlignObj::kSDD2);
-    AlignLayer(AliAlignObj::kSSD1);
-    AlignLayer(AliAlignObj::kSSD2);
-    AlignLayer(AliAlignObj::kTPC1);
-    AlignLayer(AliAlignObj::kTPC2);
-    AlignLayer(AliAlignObj::kTRD1);
-    AlignLayer(AliAlignObj::kTRD2);
-    AlignLayer(AliAlignObj::kTRD3);
-    AlignLayer(AliAlignObj::kTRD4);
-    AlignLayer(AliAlignObj::kTRD5);
-    AlignLayer(AliAlignObj::kTRD6);
-    AlignLayer(AliAlignObj::kTOF);
-    // Again inward
-    AlignLayer(AliAlignObj::kTRD6);
-    AlignLayer(AliAlignObj::kTRD5);
-    AlignLayer(AliAlignObj::kTRD4);
-    AlignLayer(AliAlignObj::kTRD3);
-    AlignLayer(AliAlignObj::kTRD2);
-    AlignLayer(AliAlignObj::kTRD1);
-    AlignLayer(AliAlignObj::kTPC2);
+    AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
+    iterations--;
   }
 }
 
@@ -435,110 +415,215 @@ void AliAlignmentTracks::AlignLayer(AliAlignObj::ELayerID layer,
   // a given layer.
   // Tracks are fitted only within
   // the range defined by the user.
+  Int_t nModules = AliAlignObj::LayerSize(layer);
+  TArrayI volIds(nModules);
+  for (Int_t iModule = 0; iModule < nModules; iModule++) {
+    UShort_t volId = AliAlignObj::LayerToVolUID(layer,iModule);
+    volIds.AddAt(volId,iModule);
+  }
+
   while (iterations > 0) {
-    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(layer); iModule++) {
-      UShort_t volId = AliAlignObj::LayerToVolUID(layer,iModule);
-      AlignVolume(volId,layerRangeMin,layerRangeMax);
-    }
+    AlignVolumes(&volIds,0x0,layerRangeMin,layerRangeMax);
     iterations--;
   }
 }
 
 //______________________________________________________________________________
-void AliAlignmentTracks::AlignVolume(UShort_t volid,
-                                    AliAlignObj::ELayerID layerRangeMin,
-                                    AliAlignObj::ELayerID layerRangeMax)
+void AliAlignmentTracks::AlignVolume(UShort_t volId, UShort_t volIdFit,
+                                    Int_t iterations)
 {
-  // Align a single detector volume.
+  // Align single detector volume to
+  // another volume.
   // Tracks are fitted only within
-  // the range defined by the user.
+  // the second volume.
+  TArrayI volIds(1);
+  volIds.AddAt(volId,0);
+  TArrayI volIdsFit(1);
+  volIdsFit.AddAt(volIdFit,0);
 
-  // First take the alignment object to be updated
-  Int_t iModule;
-  AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
-  AliAlignObj *alignObj = fAlignObjs[iLayer][iModule];
+  while (iterations > 0) {
+    AlignVolumes(&volIds,&volIdsFit);
+    iterations--;
+  }
+}
+
+//______________________________________________________________________________
+void AliAlignmentTracks::AlignVolumes(const TArrayI *volids, const TArrayI *volidsfit,
+                                    AliAlignObj::ELayerID layerRangeMin,
+                                    AliAlignObj::ELayerID layerRangeMax,
+                                    Int_t iterations)
+{
+  // Align a set of detector volumes.
+  // Tracks are fitted only within
+  // the range defined by the user
+  // (by layerRangeMin and layerRangeMax)
+  // or within the set of volidsfit
+  // Repeat the procedure 'iterations' times
+
+  Int_t nVolIds = volids->GetSize();
+  if (nVolIds == 0) {
+    AliError("Volume IDs array is empty!");
+    return;
+  }
 
-  // Then load only the tracks with at least one
-  // space point in the volume (volid)
+  // Load only the tracks with at least one
+  // space point in the set of volume (volids)
   BuildIndex();
   AliTrackPointArray **points;
-  Int_t nArrays = LoadPoints(volid, points);
-  if (nArrays == 0) return;
-
-  AliTrackResiduals *minimizer = CreateMinimizer();
-  minimizer->SetNTracks(nArrays);
-  minimizer->SetAlignObj(alignObj);
-  AliTrackFitter *fitter = CreateFitter();
-  for (Int_t iArray = 0; iArray < nArrays; iArray++) {
-    fitter->SetTrackPointArray(points[iArray], kFALSE);
-    AliTrackPointArray *pVolId = 0, *pTrack = 0;
-    fitter->Fit(volid,pVolId,pTrack,layerRangeMin,layerRangeMax);
-    minimizer->AddTrackPointArrays(pVolId,pTrack);
-  }
-  minimizer->Minimize();
+  // Start the iterations
+  while (iterations > 0) {
+    Int_t nArrays = LoadPoints(volids, points);
+    if (nArrays == 0) return;
+
+    AliTrackResiduals *minimizer = CreateMinimizer();
+    minimizer->SetNTracks(nArrays);
+    minimizer->InitAlignObj();
+    AliTrackFitter *fitter = CreateFitter();
+    for (Int_t iArray = 0; iArray < nArrays; iArray++) {
+      if (!points[iArray]) continue;
+      fitter->SetTrackPointArray(points[iArray], kFALSE);
+      if (fitter->Fit(volids,volidsfit,layerRangeMin,layerRangeMax) == kFALSE) continue;
+      AliTrackPointArray *pVolId,*pTrack;
+      fitter->GetTrackResiduals(pVolId,pTrack);
+      minimizer->AddTrackPointArrays(pVolId,pTrack);
+    }
+    minimizer->Minimize();
+
+    // Update the alignment object(s)
+    if (fDoUpdate) for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
+      UShort_t volid = (*volids)[iVolId];
+      Int_t iModule;
+      AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
+      AliAlignObj *alignObj = fAlignObjs[iLayer-AliAlignObj::kFirstLayer][iModule];      
+      *alignObj *= *minimizer->GetAlignObj();
+      alignObj->Print("");
+    }
 
-  UnloadPoints(nArrays, points);
+    UnloadPoints(nArrays, points);
+    
+    iterations--;
+  }
 }
   
 //______________________________________________________________________________
-Int_t AliAlignmentTracks::LoadPoints(UShort_t volid, AliTrackPointArray** &points)
+Int_t AliAlignmentTracks::LoadPoints(const TArrayI *volids, AliTrackPointArray** &points)
 {
   // Load track point arrays with at least
-  // one space point in a given detector
-  // volume (volid).
+  // one space point in a given set of detector
+  // volumes (array volids).
   // Use the already created tree index for
   // fast access.
-  Int_t iModule;
-  AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
-  Int_t nArrays = fLastIndex[iLayer][iModule];
 
-  // In case of empty index
-  if (nArrays == 0) {
+  if (!fPointsTree) {
+    AliError("Tree with the space point arrays not initialized!");
     points = 0;
     return 0;
   }
 
-  if (!fPointsTree) {
-    AliWarning("Tree with the space point arrays not initialized!");
+  Int_t nVolIds = volids->GetSize();
+  if (nVolIds == 0) {
+    AliError("Volume IDs array is empty!");
     points = 0;
     return 0;
   }
 
-  AliAlignObj *alignObj = fAlignObjs[iLayer][iModule];
-  TGeoHMatrix m;
-  alignObj->GetMatrix(m);
-  Double_t *rot = m.GetRotationMatrix();
-  Double_t *tr  = m.GetTranslation();
+  Int_t nArrays = 0;
+  for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
+    UShort_t volid = (*volids)[iVolId];
+    Int_t iModule;
+    AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
+
+    // In case of empty index
+    if (fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule] == 0) {
+      AliWarning(Form("There are no space-points belonging to the volume which is to be aligned (Volume ID =%d)!",volid));
+      continue;
+    }
+    nArrays += fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
+  }
+
+  if (nArrays == 0) {
+    AliError("There are no space-points belonging to all of the volumes which are to be aligned!");
+    points = 0;
+    return 0;
+  }
 
   AliTrackPointArray* array = 0;
   fPointsTree->SetBranchAddress("SP", &array);
 
+  // Allocate the pointer to the space-point arrays
   points = new AliTrackPointArray*[nArrays];
-  TArrayI *index = fArrayIndex[iLayer][iModule];
-  AliTrackPoint p;
-  Float_t xyz[3],cov[6];
-  Float_t newxyz[3];
-  for (Int_t iArray = 0; iArray < nArrays; iArray++) {
-    fPointsTree->GetEvent((*index)[iArray]);
-    if (!array) {
-      AliWarning("Wrong space point array index!");
-      continue;
-    }
-    Int_t nPoints = array->GetNPoints();
-    points[iArray] = new AliTrackPointArray(nPoints);
-    for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
-      array->GetPoint(p,iPoint);
-      p.GetXYZ(xyz,cov);
-      for (Int_t i = 0; i < 3; i++)
-       newxyz[i] = tr[i] 
-                 + xyz[0]*rot[3*i]
-                  + xyz[1]*rot[3*i+1]
-                 + xyz[2]*rot[3*i+2];
-      p.SetXYZ(newxyz,cov);
-      points[iArray]->AddPoint(iPoint,&p);
+  for (Int_t i = 0; i < nArrays; i++) points[i] = 0x0;
+
+  // Init the array used to flag already loaded tree entries
+  Bool_t *indexUsed = new Bool_t[fPointsTree->GetEntries()];
+  for (Int_t i = 0; i < fPointsTree->GetEntries(); i++)
+    indexUsed[i] = kFALSE;
+
+  // Start the loop over the volume ids
+  Int_t iArray = 0;
+  for (Int_t iVolId = 0; iVolId < nVolIds; iVolId++) {
+    UShort_t volid = (*volids)[iVolId];
+    Int_t iModule;
+    AliAlignObj::ELayerID iLayer = AliAlignObj::VolUIDToLayer(volid,iModule);
+
+    Int_t nArraysId = fLastIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
+    TArrayI *index = fArrayIndex[iLayer-AliAlignObj::kFirstLayer][iModule];
+    AliTrackPoint p;
+
+    for (Int_t iArrayId = 0; iArrayId < nArraysId; iArrayId++) {
+
+      // Get tree entry
+      Int_t entry = (*index)[iArrayId];
+      if (indexUsed[entry] == kTRUE) continue;
+      fPointsTree->GetEvent(entry);
+      if (!array) {
+       AliWarning("Wrong space point array index!");
+       continue;
+      }
+      indexUsed[entry] = kTRUE;
+
+      // Get the space-point array
+      Int_t nPoints = array->GetNPoints();
+      points[iArray] = new AliTrackPointArray(nPoints);
+      for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
+       array->GetPoint(p,iPoint);
+       Int_t modnum;
+       AliAlignObj::ELayerID layer = AliAlignObj::VolUIDToLayer(p.GetVolumeID(),modnum);
+       // check if the layer id is valid
+       if ((layer < AliAlignObj::kFirstLayer) ||
+           (layer >= AliAlignObj::kLastLayer)) {
+         AliError(Form("Layer index is invalid: %d (%d -> %d) !",
+                       layer,AliAlignObj::kFirstLayer,AliAlignObj::kLastLayer-1));
+         continue;
+       }
+       if ((modnum >= AliAlignObj::LayerSize(layer)) ||
+           (modnum < 0)) {
+         AliError(Form("Module number inside layer %d is invalid: %d (0 -> %d)",
+                       layer,modnum,AliAlignObj::LayerSize(layer)));
+         continue;
+       }
+
+       // Misalignment is introduced here
+       // Switch it off in case of real
+       // alignment job!
+       if (fMisalignObjs) {
+         AliAlignObj *misalignObj = fMisalignObjs[layer-AliAlignObj::kFirstLayer][modnum];
+         if (misalignObj)
+           misalignObj->Transform(p);
+       }
+       // End of misalignment
+
+       AliAlignObj *alignObj = fAlignObjs[layer-AliAlignObj::kFirstLayer][modnum];
+       alignObj->Transform(p);
+       points[iArray]->AddPoint(iPoint,&p);
+      }
+      iArray++;
     }
   }
 
+
+  delete [] indexUsed;
+
   return nArrays;
 }
 
@@ -575,3 +660,51 @@ AliTrackResiduals *AliAlignmentTracks::CreateMinimizer()
 
   return fMinimizer;
 }
+
+//______________________________________________________________________________
+Bool_t AliAlignmentTracks::Misalign(const char *misalignObjFileName, const char* arrayName)
+{
+  // The method reads from a file a set of AliAlignObj which are
+  // then used to apply misalignments directly on the track
+  // space-points. The method is supposed to be used only for
+  // fast development and debugging of the alignment algorithms.
+  // Be careful not to use it in the case of 'real' alignment
+  // scenario since it will bias the results.
+
+  // Initialize the misalignment objects array
+  Int_t nLayers = AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer;
+  fMisalignObjs = new AliAlignObj**[nLayers];
+  for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
+    fMisalignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer)];
+    for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer + AliAlignObj::kFirstLayer); iModule++)
+      fMisalignObjs[iLayer][iModule] = 0x0;
+  }
+
+  // Open the misliagnment file and load the array with
+  // misalignment objects
+  TFile* inFile = TFile::Open(misalignObjFileName,"READ");
+  if (!inFile || !inFile->IsOpen()) {
+    AliError(Form("Could not open misalignment file %s !",misalignObjFileName));
+    return kFALSE;
+  }
+
+  TClonesArray* array = ((TClonesArray*) inFile->Get(arrayName));
+  if (!array) {
+    AliError(Form("Could not find misalignment array %s in the file %s !",arrayName,misalignObjFileName));
+    inFile->Close();
+    return kFALSE;
+  }
+  inFile->Close();
+
+  // Store the misalignment objects for further usage  
+  Int_t nObjs = array->GetEntriesFast();
+  AliAlignObj::ELayerID layerId; // volume layer
+  Int_t modId; // volume ID inside the layer
+  for(Int_t i=0; i<nObjs; i++)
+    {
+      AliAlignObj* alObj = (AliAlignObj*)array->UncheckedAt(i);
+      alObj->GetVolUID(layerId,modId);
+      fMisalignObjs[layerId-AliAlignObj::kFirstLayer][modId] = alObj;
+    }
+  return kTRUE;
+}