diff --git a/macro/geometry/CMakeLists.txt b/macro/geometry/CMakeLists.txt
index c9ac2f44e92bb86af308ae7afcadd541a75f39df..5a8c146dfb305fca0aee66c339b0e5b40616466e 100644
--- a/macro/geometry/CMakeLists.txt
+++ b/macro/geometry/CMakeLists.txt
@@ -62,6 +62,22 @@ foreach(setup IN LISTS setup_files)
 endforeach(setup IN LISTS setup_files)
 # ============================================================================
 
+# Example of usage to check overlaps in aligned setup
+if(${CBM_TEST_MODEL} MATCHES Nightly OR ${CBM_TEST_MODEL} MATCHES Weekly)
+    set(setup mcbm_beam_2022_05_23_nickel)
+    set(align_file ${CBMROOT_SOURCE_DIR}/parameters/mcbm/AlignmentMatrices_mcbm_beam_2022_05_23_nickel.root)
+    set(testname geo_setup_overlaps_align_${setup})
+    add_test(${testname} ${MACRO_DIR}/check_overlaps.sh \"data/examine_${setup}\" \"${align_file}\")
+    set_tests_properties(${testname} PROPERTIES
+        TIMEOUT 600
+        FAIL_REGULAR_EXPRESSION "segmentation violation"
+        PASS_REGULAR_EXPRESSION "Test Passed;All ok"
+        FIXTURES_REQUIRED fixt_check_overlaps_${setup}
+        FIXTURES_SETUP fixt_check_overlaps_align_${setup}
+    )
+endIf()
+# ============================================================================
+
 Install(FILES .rootrc examine_materials.C check_overlaps.C
         DESTINATION share/cbmroot/macro/geometry
        )
diff --git a/macro/geometry/README.md b/macro/geometry/README.md
index dc4f35f75c140ebc3de23bb3d055e537bc45e1e0..4b639e4ed44624728d28f63f0e21ca13bea20a0a 100644
--- a/macro/geometry/README.md
+++ b/macro/geometry/README.md
@@ -219,5 +219,26 @@ root -q 'examine_materials.C("sis100_muon_jpsi_DEC21")'
 
  for file in `ls ../../geometry/setup/setup_mcbm_beam_2022_*`; do tag=`echo $file | awk -F'/' '{print $5}' | sed 's|setup_|"|'  | sed 's_.C$_"_'`; echo $tag; root -q './examine_material.C('$tag')'; done > MCBM_2022_EXAMINE
 
+---
 
+## check_overlaps.C
+
+Allow to check overlaps in existing full geometry file (setup, e.g. output of `examine_materials.C`) and detect
+expected/unexpected ones.
+
+The lists of expected (known and ignored) overlaps are defined in 4 vectors at the begining of the macro for:
+- overlaps between a BMon detector defined in the TOF geometry and the target/pipe vacuum in mCBM (always expected)
+- overlaps in mCBM (should be expanded/reduced depending on simulation/analysis progresses)
+- overlaps between a BMon detector defined in the TOF geometry and the target/pipe vacuum in CBM (always expected)
+- overlaps in CBM (should be expanded/reduced depending on simulation/analysis progresses)
+
+**Usage of the script (see also examples in `CMakeLists.txt`:**
+1. With a standard geometry (as defined in setup file, no alignment):
+   ```
+   root -l -b -q 'check_overlaps.C("<full filename with path>.geo.root")'
+   ```
+1. With an aligned geometry (some shifts relative to setup file):
+   ```
+   root -l -b -q 'check_overlaps.C("<full filename with path>.geo.root", "<full filename with path for alignment matrices>.root")'
+   ```
 
diff --git a/macro/geometry/check_overlaps.C b/macro/geometry/check_overlaps.C
index 92754e5f4db4b226965a6541273efd5bdc244fff..f822d74d8f4fa13899f13001431307eb8e720dde 100644
--- a/macro/geometry/check_overlaps.C
+++ b/macro/geometry/check_overlaps.C
@@ -2,7 +2,154 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese, P.-A. Loizeau, Florian Uhlig [committer] */
 
+/**********************************************************************************************************************/
+#include "FairLogger.h"
+namespace geo_ci
+{
+  /**
+   ** Temporary solution to bring capability of checking geometries after alignment.
+   ** Basically a copy of the FairAlignmentHandler of FairRoot v18.6.9 and v18.8.1
+   ** FIXME: remove once a solution is found to make the FairRoot alignment functionalities available in ROOT CLI.
+   **/
+  class FairAlignmentHandler {
+  public:
+    std::map<std::string, TGeoHMatrix> fAlignmentMatrices;
+
+    void AlignGeometry() const;
+    void AlignGeometryByFullPath() const;
+    void AlignGeometryBySymlink() const;
+
+    void AddAlignmentMatrices(const std::map<std::string, TGeoHMatrix>& alignmentMatrices, bool invertMatrices);
+
+    void RecomputePhysicalAssmbBbox() const;
+
+    FairAlignmentHandler();
+    virtual ~FairAlignmentHandler();
+  };
+  /**********************************************************************************************************************/
+  /**********************************************************************************************************************/
+  FairAlignmentHandler::FairAlignmentHandler() {}
+
+  FairAlignmentHandler::~FairAlignmentHandler() {}
+
+  void FairAlignmentHandler::AlignGeometry() const
+  {
+    if (fAlignmentMatrices.size() > 0) {
+      LOG(info) << "aligning the geometry...";
+
+      LOG(info) << "aligning in total " << fAlignmentMatrices.size() << " volumes.";
+      if (gGeoManager->GetNAlignable() > 0) {  //
+        AlignGeometryBySymlink();
+      }
+      else {
+        AlignGeometryByFullPath();
+      }
+
+      // --- Force BoundingBox recomputation for AssemblyVolumes as they may have been corrupted by alignment
+      // FIXME: will hopefully be fixed in Root in near future, temp fix in meantime
+      RecomputePhysicalAssmbBbox();
+
+      LOG(info) << "Refreshing geometry...";
+      gGeoManager->RefreshPhysicalNodes(kFALSE);
+
+      LOG(info) << "alignment finished!";
+    }
+  }
+
+  void FairAlignmentHandler::AlignGeometryByFullPath() const
+  {
+    TString volume_path;
+
+    LOG(info) << "aligning using full path.";
+    for (auto const& alignment_entry : fAlignmentMatrices) {
+      volume_path = alignment_entry.first;
+
+      gGeoManager->cd(volume_path);
+
+      TGeoNode* volume_node     = gGeoManager->GetCurrentNode();
+      TGeoMatrix* volume_matrix = volume_node->GetMatrix();
+      // Need to do this as since ROOT 6.14 TGeoMatrix has no multiplication operator anymore
+      // it is implimnted now in TGeoHMatrix
+
+      TGeoHMatrix local_volume_matrix = TGeoHMatrix(*volume_matrix);
+
+      TGeoHMatrix* new_volume_matrix = new TGeoHMatrix(local_volume_matrix * alignment_entry.second);
+      // new matrix, representing real position (from new local mis RS to the global one)
+
+      TGeoPhysicalNode* pn = gGeoManager->MakePhysicalNode(volume_path);
+
+      pn->Align(new_volume_matrix);
+    }
+    LOG(info) << "alignments applied!";
+  }
+
+  void FairAlignmentHandler::AlignGeometryBySymlink() const
+  {
+    TString volume_path;
+
+    LOG(info) << "aligning using symlinks";
+    for (auto const& alignment_entry : fAlignmentMatrices) {
+      volume_path = alignment_entry.first;
+
+      TGeoPhysicalNode* node = NULL;
+      TGeoPNEntry* entry     = gGeoManager->GetAlignableEntry(volume_path);
+      if (entry) {  //
+        node = gGeoManager->MakeAlignablePN(entry);
+      }
+
+      TGeoMatrix* volume_matrix = NULL;
+      if (node) {  //
+        volume_matrix = node->GetMatrix();
+      }
+      else {
+        continue;
+      }
+      // Need to do this as since ROOT 6.14 TGeoMatrix has no multiplication operator anymore
+      // it is implimnted now in TGeoHMatrix
+      TGeoHMatrix local_volume_matrix = TGeoHMatrix(*volume_matrix);
+
+      TGeoHMatrix* new_volume_matrix = new TGeoHMatrix(local_volume_matrix * alignment_entry.second);
+      // new matrix, representing real position (from new local mis RS to the global one)
+      node->Align(new_volume_matrix);
+    }
+  }
+
+  void FairAlignmentHandler::AddAlignmentMatrices(const std::map<std::string, TGeoHMatrix>& alignmentMatrices,
+                                                  bool invertMatrices)
+  {
+    LOG(info) << "adding inverting matrices...";
+    for (auto const& m : alignmentMatrices) {
+      if (invertMatrices)  //
+        fAlignmentMatrices[m.first] *= m.second.Inverse();
+      else
+        fAlignmentMatrices[m.first] *= m.second;
+    }
+  }
+
+  void FairAlignmentHandler::RecomputePhysicalAssmbBbox() const
+  {
+    TObjArray* pPhysNodesArr = gGeoManager->GetListOfPhysicalNodes();
+
+    TGeoPhysicalNode* pPhysNode  = nullptr;
+    TGeoShapeAssembly* pShapeAsb = nullptr;
+
+    Int_t iNbNodes = pPhysNodesArr->GetEntriesFast();
+    for (Int_t iInd = 0; iInd < iNbNodes; ++iInd) {
+      pPhysNode = dynamic_cast<TGeoPhysicalNode*>(pPhysNodesArr->At(iInd));
+      if (pPhysNode) {
+        pShapeAsb = dynamic_cast<TGeoShapeAssembly*>(pPhysNode->GetShape());
+        if (pShapeAsb) {
+          // Should reach here only if the original node was a TGeoShapeAssembly
+          pShapeAsb->ComputeBBox();
+        }
+      }
+    }
+  }
+}  // namespace geo_ci
+/**********************************************************************************************************************/
+
 std::vector<std::string> mcbm_pipevac_bmon_overlaps = {
+  "cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v19d_mcbm_0/tof_v19d_mcbmStand_1/module_5_0",
   "cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v19e_mcbm_0/tof_v19e_mcbmStand_1/module_5_0",
   "cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v20f_mcbm_0/tof_v20f_mcbmStand_1/module_5_0",
   "cave/pipe_v19f_0/vacu20_1 overlapping cave/tof_v20c_mcbm_0/tof_v20c_mcbmStand_1/module_5_0",
@@ -20,6 +167,7 @@ std::vector<std::pair<std::string, std::string>> mcbm_dets_overlaps = {
    "between modules 2 and 9 (internal to mTOF v21j)"}};
 
 std::vector<std::pair<std::string, std::string>> mcbm_dets_overlaps_sampling = {
+  {"tof_v19d_mcbmStand: node module_8_0 overlapping module_8_0", "between module 8 and itself (internal to mTOF v19d)"},
   {"tof_v19e_mcbmStand: node module_8_0 overlapping module_8_0", "between module 8 and itself (internal to mTOF v19e)"},
   {"gas_box: node counter_0 overlapping counter_1", "between counters 0 and 1 (internal to mTOF v19e)"},
   {"gas_box: node counter_1 overlapping counter_2", "between counters 1 and 2 (internal to mTOF v19e)"},
@@ -116,14 +264,15 @@ bool expected_cbm_sampling(TGeoOverlap* ov)
   return false;
 }
 
-void check_overlaps(TString dataset = "test")
+void check_overlaps(TString dataset = "test", TString alignment_matrices = "")
 {
-  // 2014-07-04 - DE - test CBM setups for collisions in nightly tests
-  // 2014-07-04 - DE - currently there are 2 overlaps between the PIPE and STS layer 8
-  // 2014-07-04 - DE - set the default to 0 overlaps, anyway
-  // 2017-29-11 - FU - define some expected overlaps between magnet and rich or much
-  //                   these overlas are accepted for the time being until
-  //                   there is a new magnet geometry
+  // 2014-07-04 - DE  - test CBM setups for collisions in nightly tests
+  // 2014-07-04 - DE  - currently there are 2 overlaps between the PIPE and STS layer 8
+  // 2014-07-04 - DE  - set the default to 0 overlaps, anyway
+  // 2017-29-11 - FU  - define some expected overlaps between magnet and rich or much
+  //                    these overlaps are accepted for the time being until there is a new magnet geometry
+  // 2023-07-xx - PAL - Test all setups in nightly tests, make the list of expected overlaps less ad-hoc,
+  //                    add all mCBM ones as expected, add a few CBM ones, create redmine issues for the rest
 
   UInt_t unexpectedOverlaps {0};
 
@@ -136,6 +285,37 @@ void check_overlaps(TString dataset = "test")
 
   gGeoManager = (TGeoManager*) f->Get("FAIRGeom");
 
+  if ("" != alignment_matrices) {
+
+    std::cout << " Applying alignment matrices from file " << alignment_matrices << std::endl;
+    // Define the basic structure which needs to be filled with information
+    // This structure is stored in the output file and later passed to the
+    // FairRoot framework to do the (miss)alignment
+    std::map<std::string, TGeoHMatrix>* matrices {nullptr};
+
+    // read matrices from disk
+    TFile* misalignmentMatrixRootfile = new TFile(alignment_matrices, "READ");
+    if (misalignmentMatrixRootfile->IsOpen()) {
+      gDirectory->GetObject("MisalignMatrices", matrices);
+      misalignmentMatrixRootfile->Close();
+    }
+    else {
+      std::cout << "Could not open file " << alignment_matrices << "\n Exiting";
+      return;
+    }
+
+    if (matrices) {
+      geo_ci::FairAlignmentHandler* handler = new geo_ci::FairAlignmentHandler();
+      handler->AddAlignmentMatrices(*matrices, false);
+      handler->AlignGeometry();
+      delete handler;
+    }
+    else {
+      std::cout << "Alignment required but no matrices found. \n Exiting";
+      return;
+    }
+  }
+
   gGeoManager->CheckOverlaps(0.0001);
   TIter next(gGeoManager->GetListOfOverlaps());
   TGeoOverlap* ov;