diff --git a/reco/alignment/CbmBbaAlignmentTask.cxx b/reco/alignment/CbmBbaAlignmentTask.cxx
index 536a380bbcb92c56337d8e4c70850ac79ecb8a02..3e854451a176d63b5e4f531154bb347126935d74 100644
--- a/reco/alignment/CbmBbaAlignmentTask.cxx
+++ b/reco/alignment/CbmBbaAlignmentTask.cxx
@@ -16,6 +16,7 @@
 // ROOT headers
 
 #include "FairRootManager.h"
+#include "FairRunAna.h"
 #include "TClonesArray.h"
 #include "TFile.h"
 #include "TGeoPhysicalNode.h"
@@ -296,6 +297,8 @@ void CbmBbaAlignmentTask::Exec(Option_t* /*opt*/)
   ca::Framework* l1                     = CbmL1::Instance()->fpAlgo;
   const ca::Parameters<ca::fvec>& l1Par = l1->GetParameters();
 
+  fFitter.SetDoSmooth(true);
+
   // select tracks for alignment and store them
   if (fTrackingMode == kSts && fInputStsTracks) {
 
@@ -334,7 +337,6 @@ void CbmBbaAlignmentTask::Exec(Option_t* /*opt*/)
 
     fFitter.SetDefaultMomentumForMs(0.5);
     fFitter.FixMomentumForMs(true);
-    fFitter.SetDoSmooth(true);
 
     for (int iTr = 0; iTr < fInputGlobalTracks->GetEntriesFast(); iTr++) {
       if (static_cast<int>(fTracks.size()) >= fMaxNtracks) {
@@ -372,63 +374,60 @@ void CbmBbaAlignmentTask::Exec(Option_t* /*opt*/)
         LOG(warning) << "failed to fit the track! ";
         continue;
       }
+      t.fAlignedTrack = t.fUnalignedTrack;
+      fTracks.push_back(t);
+    }
+  }  // end of mcbm tracking mode
 
-      // fix the material radiation thickness to avoid the chi2 rattling at the material map bin boundaries
-      // (to be improved)
-      {
-        bool isGood = true;
-        for (unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
-          CbmKfTrackFitter::FitNode& node = t.fUnalignedTrack.fNodes[in];
-          if (!node.fIsFitted) {
-            isGood = false;
-            break;
-          }
-          node.fIsRadThickFixed = true;
-          if (node.fRadThick > 0.01) {
-            LOG(warning) << "CbmBbaAlignmentTask: radiation thickness is too large: " << node.fRadThick;
-            node.fRadThick = 0.01;
-          }
-          if (node.fRadThick < 0.001) {
-            LOG(warning) << "CbmBbaAlignmentTask: radiation thickness is too small: " << node.fRadThick;
-            node.fRadThick = 0.001;
-          }
-        }
-        if (!isGood) continue;
-      }
 
-      // ensure that all the hits are not too much deviated from the trajectory
-      // (to be improved)
-      {
-        bool isGood       = true;
-        const double cutX = 8.;
-        const double cutY = 8.;
-        for (unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
-          CbmKfTrackFitter::Track tr      = t.fUnalignedTrack;
-          CbmKfTrackFitter::FitNode& node = tr.fNodes[in];
-          if (!node.fIsXySet) {
-            continue;
-          }
-          node.fIsXySet = false;  // exclude the node from the fit
-          if (!fFitter.FitTrack(tr)) {
-            isGood = false;
-            break;
-          }
-          double x_residual = node.fMxy.X() - node.fTrack.X();  // this should be the difference vector
-          double y_residual = node.fMxy.Y() - node.fTrack.Y();
-          double x_pull     = x_residual / sqrt(node.fMxy.Dx2() + node.fTrack.GetCovariance(0, 0));
-          double y_pull     = y_residual / sqrt(node.fMxy.Dy2() + node.fTrack.GetCovariance(1, 1));
-          if (!node.fIsFitted || (node.fMxy.NdfX() > 0. && fabs(x_pull) > cutX)
-              || (node.fMxy.NdfY() > 0. && fabs(y_pull) > cutY)) {
-            isGood = false;
-            break;
-          }
-        }
-        if (!isGood) continue;
+  // fix the material radiation thickness to avoid the chi2 rattling at the material map bin boundaries
+  // (to be improved)
+  for (TrackContainer& t : fTracks) {
+    if (!t.fIsActive) continue;
+    for (unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
+      CbmKfTrackFitter::FitNode& node = t.fUnalignedTrack.fNodes[in];
+      if (!node.fIsFitted) {
+        t.fIsActive = false;
+        break;
       }
+      node.fIsRadThickFixed = true;
+      if (node.fRadThick > 0.01) {
+        LOG(warning) << "CbmBbaAlignmentTask: radiation thickness is too large: " << node.fRadThick;
+        node.fRadThick = 0.01;
+      }
+      if (node.fRadThick < 0.001) {
+        LOG(warning) << "CbmBbaAlignmentTask: radiation thickness is too small: " << node.fRadThick;
+        node.fRadThick = 0.001;
+      }
+    }
+  }
 
-      t.fAlignedTrack = t.fUnalignedTrack;
-
-      fTracks.push_back(t);
+  // ensure that all the hits are not too much deviated from the trajectory
+  // (to be improved)
+  for (TrackContainer& t : fTracks) {
+    if (!t.fIsActive) continue;
+    const double cutX = 8.;
+    const double cutY = 8.;
+    for (unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
+      CbmKfTrackFitter::Track tr      = t.fUnalignedTrack;
+      CbmKfTrackFitter::FitNode& node = tr.fNodes[in];
+      if (!node.fIsXySet) {
+        continue;
+      }
+      node.fIsXySet = false;  // exclude the node from the fit
+      if (!fFitter.FitTrack(tr)) {
+        t.fIsActive = false;
+        break;
+      }
+      double x_residual = node.fMxy.X() - node.fTrack.X();  // this should be the difference vector
+      double y_residual = node.fMxy.Y() - node.fTrack.Y();
+      double x_pull     = x_residual / sqrt(node.fMxy.Dx2() + node.fTrack.GetCovariance(0, 0));
+      double y_pull     = y_residual / sqrt(node.fMxy.Dy2() + node.fTrack.GetCovariance(1, 1));
+      if (!node.fIsFitted || (node.fMxy.NdfX() > 0. && fabs(x_pull) > cutX)
+          || (node.fMxy.NdfY() > 0. && fabs(y_pull) > cutY)) {
+        t.fIsActive = false;
+        break;
+      }
     }
   }
 
@@ -505,9 +504,15 @@ void CbmBbaAlignmentTask::ApplyAlignment(const std::vector<double>& par)
       double dy = parConstrained[3 * s.fAlignmentBody + 1];
       double dz = parConstrained[3 * s.fAlignmentBody + 2];
 
+      // shift the hit
       nodeAligned.fMxy.SetX(node.fMxy.X() + dx);
       nodeAligned.fMxy.SetY(node.fMxy.Y() + dy);
       nodeAligned.fZ = node.fZ + dz;
+
+      // shift the fitted track to the Z position of the hit
+      nodeAligned.fTrack.SetX(node.fTrack.X() + node.fTrack.Tx() * dz);
+      nodeAligned.fTrack.SetY(node.fTrack.Y() + node.fTrack.Ty() * dz);
+      nodeAligned.fTrack.SetZ(node.fTrack.Z() + dz);
     }
   }
 
@@ -538,19 +543,29 @@ double CbmBbaAlignmentTask::CostFunction(const std::vector<double>& par)
   std::vector<double> chi2Thread(fNthreads, 0.);
   std::vector<long> ndfThread(fNthreads, 0);
 
-  fFitter.SetDoSmooth(false);
-
   auto fitThread = [&](int iThread) {
     CbmKfTrackFitter fit(fFitter);
+    fit.SetDoSmooth(false);
+    fit.SetNoMultipleScattering();
+
     for (unsigned int itr = iThread; itr < fTracks.size(); itr += fNthreads) {
       auto& t = fTracks[itr];
       if (!t.fIsActive) continue;
+
+      // fit.SetDebugInfo(" track " + std::to_string(itr));
+
+      for (unsigned int in = 0; in < t.fAlignedTrack.fNodes.size(); in++) {
+        CbmKfTrackFitter::FitNode& node = t.fAlignedTrack.fNodes[in];
+        if (!node.fIsFitted) {
+          LOG(fatal) << "BBA: Cost function: aligned node is not fitted! ";
+        }
+      }
       bool ok     = fit.FitTrack(t.fAlignedTrack);
       double chi2 = t.fAlignedTrack.fNodes.back().fTrack.GetChiSq();
       double ndf  = t.fAlignedTrack.fNodes.back().fTrack.GetNdf();
       if (!ok || !std::isfinite(chi2) || chi2 <= 0. || ndf <= 0.) {
+        // TODO: deactivate the track and continue
         LOG(fatal) << "BBA: fit failed! ";
-        assert(0);
         chi2 = 0.;
         ndf  = 0.;
       }
@@ -571,7 +586,6 @@ double CbmBbaAlignmentTask::CostFunction(const std::vector<double>& par)
     th.join();
   }
 
-
   fChi2Total = 0.;
   fNdfTotal  = 0;
   for (int i = 0; i < fNthreads; i++) {
@@ -663,7 +677,7 @@ void CbmBbaAlignmentTask::Finish()
     t.fAlignedTrack = t.fUnalignedTrack;
   }
 
-  if (0) {  // one alignment body per tracking station
+  if (1) {  // one alignment body per tracking station
 
     fNalignmentBodies = fNtrackingStations;
     fAlignmentBodies.resize(fNalignmentBodies);
@@ -832,19 +846,26 @@ void CbmBbaAlignmentTask::Finish()
     fCostInitial = CostFunction(parMisaligned);
     fFixedNdf    = -1;  //fNdfTotal;
 
+    // plot the residuals before alignment
 
-    for (auto& t : fTracks) {
+    for (const auto& t : fTracks) {
       if (!t.fIsActive) continue;
       // calculate the residuals for all tracks at each fitNode before alignment
       for (unsigned int in = 0; in < t.fAlignedTrack.fNodes.size(); in++) {
         CbmKfTrackFitter::Track tr      = t.fAlignedTrack;
         CbmKfTrackFitter::FitNode& node = tr.fNodes[in];
+
         if (!node.fIsXySet) {
           continue;
         }
         node.fIsXySet = false;
+
         fFitter.FitTrack(tr);
 
+        if (!node.fIsFitted) {
+          continue;
+        }
+
         Sensor& s = fSensors[node.fReference1];
 
         double x_residual = node.fMxy.X() - node.fTrack.X();  // this should be the difference vector
@@ -877,20 +898,24 @@ void CbmBbaAlignmentTask::Finish()
   LOG(info) << " Cost function for the true parameters: " << fCostIdeal;
   LOG(info) << " Cost function for the initial parameters: " << fCostInitial;
 
+  // run the alignment
   alignment.align();
 
   double costResult = CostFunction(alignment.getResult());
 
-
   CostFunction(alignment.getResult());
   CostFunction(alignment.getResult());
 
   // Create alignment matrices:
   std::vector<double> result = alignment.getResult();
   std::map<std::string, TGeoHMatrix> alignmentMatrices;
-  for (int i = 0; i < fNalignmentBodies; i++) {
+
+  for (auto& s : fSensors) {
+    int i = s.fAlignmentBody;
+    assert(i < fNalignmentBodies);
+    if (i < 0) continue;
+
     // For STS sensors
-    auto& s = fSensors[i];
     if (s.fSystemId == ECbmModuleId::kSts) {
       // get sensor for sensorID
       const CbmStsElement* el = CbmStsSetup::Instance()->GetElement(s.fSensorId, kStsSensor);
@@ -925,7 +950,7 @@ void CbmBbaAlignmentTask::Finish()
     //   alignmentMatrices.insert(AlignNode(Form("fTrackingStation %i", s.fTrackingStation), result[i * 3 + 0],
     //                                      result[i * 3 + 1], result[i * 3 + 2], 0., 0., 0.));
     // }
-  }
+  }  // sensors
 
   // save matrices to disk
   TFile* misalignmentMatrixRootfile =