diff --git a/cmake/scripts/cleanmacrodir.cmake b/cmake/scripts/cleanmacrodir.cmake
index 6d9fc36ba522aada4909633126aaaa3653062fbb..cb25470784298ef93e32ab5690e8874f9ed1dcb5 100644
--- a/cmake/scripts/cleanmacrodir.cmake
+++ b/cmake/scripts/cleanmacrodir.cmake
@@ -34,3 +34,6 @@ file(GLOB _dumpfiles
 foreach(file IN LISTS _dumpfiles)
   file(REMOVE ${file})
 endforeach()
+
+# Extra file created by transport/Geant
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/gphysi.dat)
diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt
index 32422c037a0c789be03ccf9fca2b2c19bdb2531b..174cb275feeb42dea242f6f39e880d926fb99fc9 100644
--- a/macro/CMakeLists.txt
+++ b/macro/CMakeLists.txt
@@ -7,6 +7,7 @@ add_subdirectory(mvd)
 add_subdirectory(much)
 add_subdirectory(include)
 add_subdirectory (reco)
+add_subdirectory (geometry)
 
 #--- Additional tests for nightly builds
 If(NOT ${CBM_TEST_MODEL} MATCHES Experimental)
@@ -38,7 +39,7 @@ Install(FILES ${CBMROOT_SOURCE_DIR}/scripts/loadlib.C
         DESTINATION share/cbmroot/macro/
        )
 
-Install(FILES ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_json.sh 
+Install(FILES ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_json.sh
               ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_sim_reco_json.sh
               ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_transport_json_config.C
               ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_digi_json_config.C
diff --git a/macro/geometry/.gitignore b/macro/geometry/.gitignore
index 5b897ffd934ad83f613d9ded64155a725e45d1e8..daea3e93106be005155706d40dcbe94ed1cd5b79 100644
--- a/macro/geometry/.gitignore
+++ b/macro/geometry/.gitignore
@@ -1 +1,2 @@
 geo.gv
+gphysi.dat
diff --git a/macro/geometry/CMakeLists.txt b/macro/geometry/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..261a9c128b17899a527b333e6c5e121ee7fe1ddb
--- /dev/null
+++ b/macro/geometry/CMakeLists.txt
@@ -0,0 +1,49 @@
+# =====   Generate the needed shell scripts   ================================
+GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/geometry/examine_materials.C)
+
+Set(MACRO_DIR ${CMAKE_CURRENT_BINARY_DIR})
+# ============================================================================
+
+
+# =====   Copy the .rootrc file into the directory from which root is executed
+# --- Otherwise the rootalias file is not loaded
+file(COPY ${CBMROOT_SOURCE_DIR}/macro/include/.rootrc
+     DESTINATION ${CBMROOT_BINARY_DIR}/macro/run
+    )
+# ============================================================================
+
+Set(timeOutTime 100)
+
+# =====   Cleanup the data and execution directories   =======================
+add_test(geo_cleanup ${CMAKE_COMMAND}
+	-P ${CMAKE_SOURCE_DIR}/cmake/scripts/cleanmacrodir.cmake)
+set_tests_properties(geo_cleanup PROPERTIES
+	TIMEOUT ${timeOutTime}
+	FIXTURES_SETUP geo_cleanup
+)
+# ============================================================================
+
+# =====   Define tests for each setup   ======================================
+file(GLOB setup_files
+     LIST_DIRECTORIES false
+     ${CBMROOT_SOURCE_DIR}/geometry/setup/setup_*.C
+    )
+foreach(setup IN LISTS setup_files)
+    string(REPLACE ${CBMROOT_SOURCE_DIR}/geometry/setup/setup_ "" setup ${setup})
+    string(REPLACE .C "" setup ${setup})
+    # Message("Test: found setup tag ${setup}")
+
+    # --- Test setup materials
+    # --- Check that materials in a loaded geometry (1 evt tra run) match corresponding single det geo files,
+    #     using check_materials.C
+    set(testname geo_check_mats_${setup})
+    add_test(${testname} ${MACRO_DIR}/examine_materials.sh \"${setup}\")
+    set_tests_properties(${testname} PROPERTIES
+        TIMEOUT ${timeOutTime}
+        FAIL_REGULAR_EXPRESSION "FAILED;issues with materials were detected"
+        PASS_REGULAR_EXPRESSION "SUCCESS;Excluding air and dummy materials, no material errors were detected"
+        FIXTURES_REQUIRED geo_cleanup
+        FIXTURES_SETUP fixt_check_mats_${setup}
+    )
+endforeach(setup IN LISTS setup_files)
+# ============================================================================
diff --git a/macro/geometry/data/.gitignore b/macro/geometry/data/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4ea40f8315d27f24d50e2c0f6ac12ea00b5542f6
--- /dev/null
+++ b/macro/geometry/data/.gitignore
@@ -0,0 +1 @@
+*.root
diff --git a/macro/geometry/examine_material.C b/macro/geometry/examine_materials.C
similarity index 87%
rename from macro/geometry/examine_material.C
rename to macro/geometry/examine_materials.C
index 4abc05100752efcc64f9b1b825e1939e8922c4b6..6b6a09ebff5feff161059920d599dcdb10cc298b 100644
--- a/macro/geometry/examine_material.C
+++ b/macro/geometry/examine_materials.C
@@ -13,28 +13,13 @@
 #define NODE_DEPTH 25
 
 /*  The materials in the transported TGeoManager will be compared to the materials in the subsystem binaries.
-    The general idea pre-writing will be to run transport for a user specified setup generating the TGeoManager. 
+    The general idea pre-writing will be to run transport for a user specified setup generating the TGeoManager.
     The number of volumes for each material will be recorded in a standard map. Each subsystem will be extracted
-    from the CBMSETUP, and the materials will be extraced from the respective binary and then substracted from 
+    from the CBMSETUP, and the materials will be extraced from the respective binary and then substracted from
     the from the TGeoManager version original. After going through all subsystems, if there is no volumes in the
     original standard, the two TGeoManager and the material in the subsystem match, otherwise there is a material
     mismatch detected. Output to the screen will help diagonsis. 					       */
 
-char* padd(char* source_string, unsigned int size)
-{
-
-  char* padded_string = (char*) malloc(sizeof(char) * (size + 1));
-  strncpy(padded_string, source_string, size + 1);
-
-  unsigned int i = strlen(source_string);
-  if (i < size)
-    for (; i < size; i++)
-      padded_string[i] = ' ';
-  padded_string[size] = '\0';
-
-  return padded_string;
-};
-
 typedef struct MAT_VOL mat_vol_t;
 
 struct MAT_VOL {
@@ -98,7 +83,7 @@ int extract_mat_vol(char* fileName, mat_vol_t* material_array)
     exit(1);
   };
 
-  TObjArray* nodes = top->GetNodes();
+  TObjArray* nodes = (TObjArray*) (top->GetNodes());
 
   int i_array[NODE_DEPTH], num_array[NODE_DEPTH], j;
   for (int i = 0; i < NODE_DEPTH; i++)
@@ -142,19 +127,21 @@ int extract_mat_vol(char* fileName, mat_vol_t* material_array)
   return 0;
 }
 
-int examine_material(const char* setup = "sis100_electron")
+int examine_materials(const char* setup = "sis100_electron")
 {
   TString srcDir    = gSystem->Getenv("VMCWORKDIR");
   ECbmEngine engine = kGeant3;
 
   CbmTransport run;
   run.SetEngine(engine);
-  run.AddInput(srcDir + "/input/urqmd.auau.10gev.centr.root", kUnigen);
-  run.SetOutFileName("examine.tra.root", kTRUE);
-  run.SetParFileName("examaine.par.root");
-  run.SetGeoFileName("examine.geo.root");
+  run.SetOutFileName(Form("data/examine_%s.tra.root", setup), kTRUE);
+  run.SetParFileName(Form("data/examine_%s.par.root", setup));
+  run.SetGeoFileName(Form("data/examine_%s.geo.root", setup));
   run.LoadSetup(setup);
+  run.SetField(new CbmFieldConst());  // Avoid crash for setups without field as not real simu (COSY, mCBM, ...)
+  // Shoot single 10 GeV proton straight through the pipe to minimize transport
   run.SetBeamPosition(0, 0, 0.1, 0.1);
+  run.AddInput(new CbmBeamGenerator(1, 1, 1, 10., 0));
   run.SetRandomSeed(1234);  // I fix this number so everything is deterministic
   run.Run(1);
 
@@ -164,7 +151,7 @@ int examine_material(const char* setup = "sis100_electron")
     strcpy(transport_materials[i].name, "");
   };
 
-  extract_mat_vol("examine.geo.root", transport_materials);
+  extract_mat_vol(Form("data/examine_%s.geo.root", setup), transport_materials);
 
   // Detector and passive subsystems
   for (int i = 0; i < 120; i++)
@@ -240,19 +227,19 @@ int examine_material(const char* setup = "sis100_electron")
   };
   (void) printf("TOTAL NUMBER OF VOLUMES\tTRANSPORTED: %d\t DETECTORS: %d\n", SUMT, SUMD);
 
-  printf("%s\t\tTransported\t\tSubsystems\t\tDifference \n", padd("Material", 25));
+  printf("%-25s\t\tTransported\t\tSubsystems\t\tDifference \n", "Material");
   int FAIL = 0;  // Success
   int DIFF = 0;
 
   for (int i = 0; i < MAX_MATERIALS; i++) {
     if (0 < (transport_materials + i)->count) {
-      printf("%s\t\t%d", padd((transport_materials + i)->name, 25), (transport_materials + i)->count);
+      printf("%-25s\t\t%9d", (transport_materials + i)->name, (transport_materials + i)->count);
       for (int j = 0; j < MAX_MATERIALS; j++) {
         if (!strcmp((transport_materials[i].name), (detector_materials[j].name)))
-          printf("\t\t%d", (detector_materials + i)->count);
+          printf("\t\t%9d", (detector_materials + i)->count);
       };
       DIFF = ((transport_materials + i)->count) - ((detector_materials + i)->count);
-      printf("\t\t%d\n", DIFF);
+      printf("\t\t%9d\n", DIFF);
     };
     if ((strcmp(transport_materials[i].name, "dummy") != 0) && (strcmp(transport_materials[i].name, "air") != 0))
       FAIL += abs(DIFF);