From fdc6418d43145b6347afcc4434bde07287a81e7d Mon Sep 17 00:00:00 2001
From: Volker Friese <v.friese@gsi.de>
Date: Tue, 17 Nov 2020 11:59:35 +0100
Subject: [PATCH] New or modified transport macros for file input
 (run_tra_file.C and beam simulation (run_tra_beam.C). Added three regular
 tests: transport of collision events, transport of signal events (from PLUTO)
 and transport of beam events.

---
 cmake/scripts/cleanmacrodir.cmake             |  36 ++
 macro/C2F/CMakeLists.txt                      |   7 +-
 macro/dimuon/CMakeLists.txt                   |   5 +-
 macro/much/CMakeLists.txt                     |   4 +-
 macro/run/CMakeLists.txt                      | 332 ++++++------
 macro/run/run_digi.C                          | 170 +++---
 macro/run/run_reco.C                          | 484 ++++++++++++++++++
 macro/run/run_tra_beam.C                      | 176 +++++++
 macro/run/run_tra_file.C                      | 175 +++++++
 macro/run/run_transport_beam.C                | 134 -----
 reco/detectors/sts/CbmStsFindTracksEvents.cxx |   8 +-
 sim/transport/steer/CbmSimSteerLinkDef.h      |   1 +
 12 files changed, 1158 insertions(+), 374 deletions(-)
 create mode 100644 cmake/scripts/cleanmacrodir.cmake
 create mode 100644 macro/run/run_reco.C
 create mode 100644 macro/run/run_tra_beam.C
 create mode 100644 macro/run/run_tra_file.C
 delete mode 100644 macro/run/run_transport_beam.C

diff --git a/cmake/scripts/cleanmacrodir.cmake b/cmake/scripts/cleanmacrodir.cmake
new file mode 100644
index 0000000000..b6b5a03b18
--- /dev/null
+++ b/cmake/scripts/cleanmacrodir.cmake
@@ -0,0 +1,36 @@
+# CMake macro for cleaning up the current directory
+# F. Uhlig, 14 November 2020
+# The macro removes all files from the subdirectory "data", all files matching
+# the pattern all*.par, and all core dump files.
+#
+# Cleaning up the data directory as first step of a test suite provides a clean
+# state and prevents accidental usage of files generated in previous tests.
+# This is of particular relevance e.g., for ROOT parameter files, which will
+# be updated instead of re-generated by successive test runs. 
+
+Message("Remove all files from directory ${CMAKE_CURRENT_BINARY_DIR}/data")
+file(GLOB _deletefiles
+     LIST_DIRECTORIES false
+     ${CMAKE_CURRENT_BINARY_DIR}/data/*
+    )
+foreach(file IN LISTS _deletefiles)
+  file(REMOVE ${file})
+endforeach()
+
+Message("Remove all all*.par files from ${CMAKE_CURRENT_BINARY_DIR}")
+file(GLOB _parfiles 
+     LIST_DIRECTORIES false
+     ${CMAKE_CURRENT_BINARY_DIR}/all*.par
+    )
+foreach(file IN LISTS _parfiles)
+  file(REMOVE ${file})
+endforeach()
+
+Message("Remove all core dump files from ${CMAKE_CURRENT_BINARY_DIR}")
+file(GLOB _dumpfiles 
+     LIST_DIRECTORIES false
+     ${CMAKE_CURRENT_BINARY_DIR}/core_dump_*
+    )
+foreach(file IN LISTS _dumpfiles)
+  file(REMOVE ${file})
+endforeach()
diff --git a/macro/C2F/CMakeLists.txt b/macro/C2F/CMakeLists.txt
index d5e3792188..39445e65a5 100644
--- a/macro/C2F/CMakeLists.txt
+++ b/macro/C2F/CMakeLists.txt
@@ -18,6 +18,7 @@ Set(NumEvents 20)
 # Define the different setups to be tested
 If( ($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly) )
   List(APPEND cbm_setup sis100_electron)
+EndIf()
 
   ForEach(setup IN LISTS cbm_setup)
 
@@ -36,9 +37,10 @@ If( ($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly) )
   
     # --- Digitisation run, event-by-event
     Set(testname c2f_digi_event_${setup})
-    Add_Test(${testname} ${MACRO_DIR}/run_digi.sh ${NumEvents} \"data/${setup}_test\" 0. 0. 1)
+    Add_Test(${testname} ${MACRO_DIR}/run_digi.sh \"data/${setup}_test\" ${NumEvents} 
+    	\"data/${setup}_test.event\" -1.)
     Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "300")
-    Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+    Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Macro finished successfully")
     set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_c2f_digi})
     Set(fixture_c2f_reco_event fixture_c2f_reco_event_${testname})
     set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_c2f_reco_event})
@@ -72,7 +74,6 @@ If( ($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly) )
 
   EndForEach(setup IN LISTS cbm_setup)
   # end of test CBM setups from geometry/setup
-EndIf()
 
 Install(FILES .rootrc c2f_transport.C 
         DESTINATION share/cbmroot/macro/c2f
diff --git a/macro/dimuon/CMakeLists.txt b/macro/dimuon/CMakeLists.txt
index aa4564acd2..d22c848cad 100644
--- a/macro/dimuon/CMakeLists.txt
+++ b/macro/dimuon/CMakeLists.txt
@@ -35,9 +35,10 @@ If( ($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly) )
   
     # --- Digitisation run, event-by-event
     Set(testname dimuon_digi_event_${setup})
-    Add_Test(${testname} ${MACRO_DIR}/run_digi.sh ${NumEvents} \"data/${setup}_test\" 0. 0. 1)
+    Add_Test(${testname} ${MACRO_DIR}/run_digi.sh \"data/${setup}_test\" ${NumEvents} 
+    	\"data/${setup}_test.event\" -1.)
     Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "300")
-    Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+    Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Macro finished successfully")
     set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_dimuon_digi})
     Set(fixture_dimuon_reco_event fixture_dimuon_reco_event_${testname})
     set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_dimuon_reco_event})
diff --git a/macro/much/CMakeLists.txt b/macro/much/CMakeLists.txt
index 8e266b0533..ec6ed21e96 100644
--- a/macro/much/CMakeLists.txt
+++ b/macro/much/CMakeLists.txt
@@ -20,9 +20,9 @@ set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP fixture_much_digi)
 
 # --- Digitisation, event-by-event
 Set(testname much_digi)
-Add_Test(${testname} ${MACRO_DIR}/run_digi.sh ${NumEvents} \"muons\" 0. 0. 1)
+Add_Test(${testname} ${MACRO_DIR}/run_digi.sh \"muons\" ${NumEvents} \"muons.event\" -1.)
 Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "1200")
-Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Macro finished successfully")
 set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED fixture_much_digi)
 set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP fixture_much_reco)
 
diff --git a/macro/run/CMakeLists.txt b/macro/run/CMakeLists.txt
index eaf838b7a4..a6d75cba39 100644
--- a/macro/run/CMakeLists.txt
+++ b/macro/run/CMakeLists.txt
@@ -1,186 +1,186 @@
-# start of test CBM setups from geometry/setup
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_transport.C)
+# =====   Generate the needed shell scripts   ================================
+GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_file.C)
+GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_beam.C)
 GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_digi.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_reco_event.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/check_overlaps.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_transport_qa.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_qa.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_reco_tb_track.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_recoqa_tb_track.C)
-GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_reco_analysis.C)
-
-Set(MACRO_DIR ${CMAKE_CURRENT_BINARY_DIR})
-GENERATE_CBM_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/geometry/check_media.C ${MACRO_DIR})
-
-# Put 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)
-
-# Define Variables for Tests
+GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_reco.C)
+# ============================================================================
+
+
+# =====   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)
+# ============================================================================
+
+
+# =====   Define variables for tests   =======================================
 if($ENV{ctest_model} MATCHES Weekly)
-  Set(NumEvents 100)
+  Set(nEvents 100)
   Set(uploadHistJPG 1)
   Set(pullDevAllowed .2)
-Else()
-  Set(NumEvents 3)
+else()
+  Set(nEvents 3)
   Set(uploadHistJPG 0)
   Set(pullDevAllowed .5)
-EndIf()
+endIf()
 
-math(EXPR timeOutTime "${NumEvents} * 200")
+math(EXPR timeOutTime "${nEvents} * 200")
+math(EXPR nBeam "${nEvents} * 3")
+# ============================================================================
 
-# Define the different setups to be tested
-If(($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly))
-  List(APPEND cbm_setup sis100_hadron sis100_electron sis100_muon_lmvm sis100_muon_jpsi sis300_electron)
-Else()
+
+# =====   Define the different setups to be tested with   ====================
+if(($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly))
+  List(APPEND cbm_setup sis100_hadron sis100_electron sis100_muon_lmvm 
+  	sis100_muon_jpsi sis300_electron)
+else()
   List(APPEND cbm_setup sis100_electron sis100_muon_jpsi)
-EndIf()
-
-ForEach(setup IN LISTS cbm_setup)
-
-  # The test dependencies are set such that parallel execution is prevented, even is there is no logical
-  # dependence. The reason is that all runs (for a given setup) use the same ROOT parameter file,
-  # and concurrent access to this file results in erros.
-  # The logical dependences are expressed in the required "ok" files.
-
-  # --- Transport run, using run_transport.C
-  Set(testname run_transport_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_transport.sh ${NumEvents} \"${setup}\" \"data/${setup}_test\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  Set(fixture_digi fixture_digi_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_digi})
+endif()
+# ============================================================================
+
+
+# =====   Cleanup the data directory   =======================================
+add_test(run_cleanup ${CMAKE_COMMAND} 
+	-P ${CMAKE_SOURCE_DIR}/cmake/scripts/cleanmacrodir.cmake)
+set_tests_properties(run_cleanup PROPERTIES 
+	TIMEOUT ${timeOutTime}
+	FIXTURES_SETUP cleanup
+)
+# ============================================================================
+
+
+# =====   Define tests for each setup   ======================================
+foreach(setup IN LISTS cbm_setup)
+
+  # --- Short name for setup
+  if(setup MATCHES sis100_hadron) 
+  	set(sname s100h)
+  elseif(setup MATCHES sis100_electron) 
+  	set(sname s100e)
+  elseif(setup MATCHES sis100_muon_lmvm) 
+  	set(sname s100m2)
+  elseif(setup MATCHES sis100_muon_jpsi) 
+  	set(sname s100m3)
+  elseif(setup MATCHES sis300_electron) 
+  	set(sname s300e)
+  else()
+  	set(sname test)
+  endif()
+
+  # --- Test run_tra_coll
+  # --- Transport run with collision events, using run_tra_file.C
+  set(testname run_${sname}_tra_coll)
+  set(input ${CBMROOT_SOURCE_DIR}/input/urqmd.auau.10gev.centr.root)
+  add_test(${testname} ${MACRO_DIR}/run_tra_file.sh 
+  	\"${input}\" ${nEvents} \"data/${sname}_coll\" \"${setup}\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+  	FIXTURES_REQUIRED cleanup
+  	FIXTURES_SETUP "fixt_digi_ts_${setup};fixt_digi_ev_${setup}"
+  	RESOURCE_LOCK collParDb_${setup}
+  )
   
-  # --- Digitisation run, event-by-event
-  Set(testname run_digi_event_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_digi.sh ${NumEvents} \"data/${setup}_test\" 0. 0. 1)
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime}/2)
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi})
-  Set(fixture_reco_event fixture_reco_event_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_reco_event})
-
-  # --- Reconstruction run, event-by-event
-  Set(testname run_reco_event_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_reco_event.sh ${NumEvents} \"data/${setup}_test\" \"${setup}\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_reco_event})
-  Set(fixture_reco_event_mc fixture_reco_event_mc_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_reco_event_mc})
+  # --- Test run_tra_sign
+  # --- Transport run with signal events, using run_tra_file.C
+  set(testname run_${sname}_tra_sign)
+  set(input ${CBMROOT_SOURCE_DIR}/input/pluto.auau.8gev.omega.mpmm.0001.root)
+  add_test(${testname} ${MACRO_DIR}/run_tra_file.sh 
+  	\"${input}\" ${nEvents} \"data/${sname}_sign\" \"${setup}\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+  	FIXTURES_REQUIRED cleanup
+  	FIXTURES_SETUP fixt_digi_ts_${setup}
+  	RESOURCE_LOCK signParDb_${setup}
+  )
   
-  # --- Reconstruction run, event-by-event, with MC input
-  Set(testname run_reco_event_mc_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_reco_event.sh ${NumEvents} \"data/${setup}_test\" \"${setup}\" 1)
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_reco_event_mc})
-  Set(fixture_qa_event_mc fixture_qa_event_mc_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_qa_event_mc})
-
-  # --- Quality Assurance
-  Set(testname run_qa_event_mc_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_qa.sh ${NumEvents} \"data/${setup}_test\" \"${setup}\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  Set_Tests_Properties(${testname} PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR")
-  Set_Tests_Properties(${testname} PROPERTIES FAIL_REGULAR_EXPRESSION "FATAL")
-  Set_Tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_qa_event_mc})
-  Set(fixture_digi_tb fixture_digi_tb_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_digi_tb})
-
-#  # --- Reconstruction Quality Assurance
-#  Set(testname run_reco_event_qa_${setup})
-#  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_reco_analysis.sh \"data/${setup}_test\" {{\"MvdCluster\",\"CbmMvdCluster\",\"MVD_Cluster_Finder\"},{\"MvdHit\",\"CbmMvdHit\",\"MVD_Hit_Finder\"},{\"StsCluster\",\"CbmStsCluster\",\"StsFindCluster\"},{\"StsHit\",\"CbmStsHit\",\"StsFindHit\"},{\"StsTrack\",\"CbmStsTrack\",\"StsFindTracksEvents\"}} {{\"sts\",{${pullDevAllowed},1,1,1}},{\"mvd\",{${pullDevAllowed},1,1,1}}} 2500 ${uploadHistJPG})
-#  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-#  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-#  Set_Tests_Properties(${testname} PROPERTIES FAIL_REGULAR_EXPRESSION "Strong Deviation")
-#  Set_Tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi_tb})
-#  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_digi_tb})
+  # --- Test run_tra_beam
+  # --- Transport run with beam events, using run_tra_beam.C
+  set(testname run_${sname}_tra_beam)
+  add_test(${testname} ${MACRO_DIR}/run_tra_beam.sh 
+  	${nBeam} \"Au\" 10 -1 \"data/${sname}_beam\" \"${setup}\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+  	FIXTURES_REQUIRED cleanup
+  	FIXTURES_SETUP fixt_digi_ts_${setup}
+  	RESOURCE_LOCK beamParDb_${setup}
+  )
+   
+  # --- Test run_digi_ev
+  # --- Detector response simulation, event-by-event, using run_digi.C
+  set(testname run_${sname}_digi_ev)
+  add_test(${testname} ${MACRO_DIR}/run_digi.sh 
+  	\"data/${sname}_coll\" -1 \"data/${sname}_ev\" -1.)
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+	FIXTURES_REQUIRED fixt_digi_ev_${setup}	 
+  	FIXTURES_SETUP fixt_reco_ev_${setup}
+ 	RESOURCE_LOCK collParDb_${setup}
+  )
  
-  # --- Digitisation run, time-based
-  Set(testname run_digi_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_digi.sh ${NumEvents} \"data/${setup}_test\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi_tb})
-  Set(fixture_reco_tb fixture_reco_tb_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_reco_tb})
+  # --- Test run_digi_ts
+  # --- Detector response simulation, time-based, using run_digi.C
+  set(testname run_${sname}_digi_ts)
+  set(eventrate 1.e7)
+  set(beamrate 1.e9)
+  set(tslength 1.e6)
+  add_test(${testname} ${MACRO_DIR}/run_digi.sh 
+  	\"data/${sname}_coll\" -1 \"data/${sname}_ts\"\ ${eventrate} ${tslength} 
+  	\"data/${sname}_sign\" \"data/${sname}_beam\" ${beamrate})
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+ 	FIXTURES_REQUIRED fixt_digi_ts_${setup}
+  	FIXTURES_SETUP fixt_reco_ts_${setup}
+ 	RESOURCE_LOCK collParDb_${setup}
+  )
+  
+  # --- Test run_reco_ev
+  # --- Event-by-event reconstruction from event-based simulation
+  set(testname run_${sname}_reco_ev)
+  add_test(${testname} ${MACRODIR}/run_reco.sh
+  	\"data/${sname}_ev\" -1 0 \"\" \"Ideal\" \"${setup}\" \"data/${sname}_coll\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+	FIXTURES_REQUIRED fixt_reco_ev_${setup}	 
+ 	RESOURCE_LOCK collParDb_${setup}
+  )
   
-  # --- Reconstruction run, Time Based
-  Set(testname run_reco_tb_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_reco_tb_track.sh \"data/${setup}_test\" -1 \"${setup}\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_reco_tb})
-  Set(fixture_reco_tb_qa fixture_reco_tb_qa_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_reco_tb_qa})
-
-  # --- Reconstruction run, Time Based
-  Set(testname run_reco_tb_qa_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_recoqa_tb_track.sh \"data/${setup}_test\" -1 \"${setup}\")
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_reco_tb_qa})
-  Set(fixture_reco_tb_ana fixture_reco_tb_ana_${testname})
-  set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_reco_tb_ana})
-
-  # --- Reconstruction Quality Assurance
-  Set(testname run_reco_tb_ana_${setup})
-  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_reco_analysis.sh \"data/${setup}_test\" {{\"StsHit\",\"CbmStsHit\",\"RecoSts\"},{\"StsTrack\",\"CbmStsTrack\",\"STSFindTracks\"}} {{\"sts\",{${pullDevAllowed},1,1,1}}} 2500 ${uploadHistJPG})
-  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-  Set_Tests_Properties(${testname} PROPERTIES FAIL_REGULAR_EXPRESSION "Strong Deviation")
-  Set_Tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_reco_tb_ana})
-  set(dep_qa_transport ${testname}) 
-
-  # --- QA run
-#  Set(testname run_transport_qa_${setup})
-#  Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/run_transport_qa.sh \"${setup}\" \"data/${setup}_test\")
-#  Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "20")
-#  Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-#  Set_Tests_Properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi})
-#  Set_Tests_Properties(${testname} PROPERTIES DEPENDS ${dep_qa_transport})
-#  set(dep_overlaps ${testname}) 
-
-
-
-  # --- Geometry checking; only for nightly test
-  If( ($ENV{ctest_model} MATCHES Nightly) OR ($ENV{ctest_model} MATCHES Weekly) )
-    Set(testname run_check_media_${setup})
-    Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/check_media.sh \"data/${setup}_test\")
-    Set_Tests_Properties(${testname} PROPERTIES TIMEOUT ${timeOutTime})
-    Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-    Set_Tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi})
-
-  	Set(testname run_overlap_${setup})
-  	Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/run/check_overlaps.sh \"data/${setup}_test\")
-  	Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "900")
-  	Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-        Set_Tests_Properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_digi})
-#        Set_Tests_Properties(${testname} PROPERTIES DEPENDS ${dep_overlaps})
-        Set_Tests_Properties(${testname} PROPERTIES DEPENDS ${dep_qa_transport})
-  EndIf()
+  # --- Test run_reco_ts_eb
+  # --- Event-by-event reconstruction from time-based simulation
+  set(testname run_${sname}_reco_ts_eb)
+  add_test(${testname} ${MACRODIR}/run_reco.sh
+  	\"data/${sname}_ts\" -1 0 \"data/${sname}_ts_eb\" \"Ideal\" \"${setup}\" 
+  	\"data/${sname}_coll\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+	FIXTURES_REQUIRED fixt_reco_ts_${setup}	 
+ 	RESOURCE_LOCK collParDb_${setup}
+  )
+  
+  # --- Test run_reco_ts_tb
+  # --- Time-based reconstruction from time-based simulation
+  set(testname run_${sname}_reco_ts_tb)
+  add_test(${testname} ${MACRODIR}/run_reco.sh
+  	\"data/${sname}_ts\" -1 0 \"data/${sname}_ts_tb\" \"\" \"${setup}\" 
+  	\"data/${sname}_coll\")
+  set_tests_properties(${testname} PROPERTIES 
+  	TIMEOUT ${timeOutTime}
+  	PASS_REGULAR_EXPRESSION "Macro finished successfully"
+	FIXTURES_REQUIRED fixt_reco_ts_${setup}	 
+ 	RESOURCE_LOCK collParDb_${setup}
+  )
  
-EndForEach(setup IN LISTS cbm_setup)
-
-# I will have to check these macros for being up-to-date or necessary
-#GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run.C)
-#add_test(run_run ${CBMROOT_BINARY_DIR}/macro/run/run.sh)
-#SET_TESTS_PROPERTIES(run_run PROPERTIES TIMEOUT "300")
-#SET_TESTS_PROPERTIES(run_run PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+endforeach(setup IN LISTS cbm_setup)
+# ============================================================================
 
-#GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/checkFields.C)
-#add_test(run_checkFields ${CBMROOT_BINARY_DIR}/macro/run/checkFields.sh)
-#SET_TESTS_PROPERTIES(run_checkFields PROPERTIES TIMEOUT "60")
 
-#GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/checkFieldMap.C)
-#add_test(run_checkFieldMap ${CBMROOT_BINARY_DIR}/macro/run/checkFieldMap.sh)
-#SET_TESTS_PROPERTIES(run_checkFieldMap PROPERTIES TIMEOUT "60")
 
-#GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/checkFieldSym.C)
-#add_test(run_checkFieldSym ${CBMROOT_BINARY_DIR}/macro/run/checkFieldSym.sh)
-#SET_TESTS_PROPERTIES(run_checkFieldSym PROPERTIES TIMEOUT "60")
 
 
 Install(FILES .rootrc run_transport.C run_digi.C run_reco_event.C check_overlaps.C 
diff --git a/macro/run/run_digi.C b/macro/run/run_digi.C
index 308e1ed2d1..31bbbb92c5 100644
--- a/macro/run/run_digi.C
+++ b/macro/run/run_digi.C
@@ -11,49 +11,75 @@
 #endif
 
 
-/** @brief run_digi
+/** @brief Macro for detector response simulation in CBM
  ** @author Volker Friese <v.friese@gsi.de>
  ** @since  8 June 2018
- ** @param nEvents    Number of events to process
- ** @param dataSet    Name of data set (input and output)
- ** @param eventRate  Interaction rate [1/s]
- ** @param tsLength   Length of time slice [ns]
+ ** @param inputEvents  Main input file (w/o extension .tra.root)
+ ** @param nEvents      Number of events to process
+ ** @param output       Name of output file (w/o extension .raw.root)
+ ** @param eventRate    Event rate [1/s]
+ ** @param tsLength     Length of time slice [ns]
+ ** @param inputSignal  Signal input file, will be embedded to the events
+ ** @param inputBeam    Third input file, will be mixed with the events
+ ** @param beamRate     Beam rate [1/s]
  **
- ** Macro for detector response simulation with CBM, for regular tests.
+ ** Macro for detector response simulation in CBM
  **
  ** The detector response produces a raw data file from the transport
  ** data, which serves as input for reconstruction. Raw data will
  ** be delivered in time-slice format (one tree entry per time-slice).
  **
- ** For the file names, the following conventions are applied:
- ** Input file:     [dataSet].tra.root
- ** Parameter file: [dataSet].par.root
- ** Output file:    [dataSet].raw.root
- ** If different names are wanted, they have to be specified
- ** explicitly in the macro.
+ ** This macro allows to simultaneously digitise three inputs, which were
+ ** separately generated in respective transport runs:
+ ** - the main event input,
+ ** - a signal input, which is embedded into the event input (optional),
+ ** - a beam input, which is mixed to the event input (optional).
+ ** Please note that it is in the user's responsibility that the input files
+ ** are consistent, i.e., the transport simulation was performed with the
+ ** same settings (geometry, engine, cuts).
  **
- ** The arguments to the macro call represent the minimal
- ** information to be passed to the digitization run. In addition, 
- ** the mode (time-based as default, or event-by-event) can be specified.
- ** By default, already existing output files will not be overwritten
- ** to prevent accidental data loss.
+ ** The input file names are expected to have the extension .tra.root.
+ ** The parameter file [inputEvents].par.root will be used also for
+ ** parameter output. if inputEvents is not specified by the user, it will
+ ** be set to "test.tra.root", to enable execution of the macro chain
+ ** run_tra_file.C and run_digi.C from the ROOT prompt without any argument.
  **
- ** If the time-slice length is negative, all data will be in one
- ** time-slice.
+ ** The output file will be [output].raw.root. If the argument output is
+ ** not specified by the user, the output file will be [inputEvents].raw.root.
  **
- ** For further options to modify the run settings, consult
- ** the documentation of the CbmDigitization class.
+ ** If the event rate is set to a negative value, the simulation will be
+ ** event-based, i.e. one time slice (with flexible time interval) will be
+ ** created for each input event. In that case, embedding and mixing is not
+ ** possible, i.e., all following arguments will be ignored.
+ **
+ ** If the time-slice length is set to a negative value, all data will be
+ ** contained in one single time-slice (entry) with flexible time interval.
+ ** Be careful with this, since it may exceed the available RAM at a certain
+ ** number of events.
+ **
+ ** The run will terminate after the specified number of input events or when
+ ** when the event input is exhausted. Entries from the beam input are taken
+ ** randomly and can thus be re-used, so the beam input cannot be exhausted.
+ ** Make sure that there is sufficient statistics in the beam input to avoid
+ ** a bias due to repeated use of beam events.
+ **
+ ** For further options to modify the run settings, the macro body must be
+ ** modified. Please consult the documentation of the CbmDigitization class
+ ** (http://computing.gitpages.cbm.gsi.de/cbmroot/classCbmDigitization.html).
  **/
-void run_digi(Int_t nEvents            = 2,       // Number of events to process
-              TString dataSet          = "test",  // Dataset for file names
-              Double_t eventRate       = 1.e7,    // Interaction rate [1/s]
-              Double_t timeSliceLength = 1.e4,    // Length of time-slice [ns]
-              Bool_t eventMode         = kFALSE   // Event-by-event mode
-) {
+void run_digi(TString inputEvents = "",
+              Int_t nEvents       = -1,
+              TString output      = "",
+              Double_t eventRate  = 1.e7,
+              Double_t tsLength   = -1.,
+              TString inputSignal = "",
+              TString inputBeam   = "",
+              Double_t beamRate   = 1.e9) {
 
   // --- Logger settings ----------------------------------------------------
   FairLogger::GetLogger()->SetLogScreenLevel("INFO");
   FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
+  TString myName = "run_digi";  // this macro's name for screen output
   // ------------------------------------------------------------------------
 
 
@@ -62,15 +88,17 @@ void run_digi(Int_t nEvents            = 2,       // Number of events to process
   // ------------------------------------------------------------------------
 
 
-  // -----   File names   ---------------------------------------------------
-  TString inFile  = dataSet + ".tra.root";
-  TString parFile = dataSet + ".par.root";
-  TString outFile = dataSet + ".raw.root";
-  TString monFile = dataSet + ".raw.moni.root";
-  if (eventMode) {
-    outFile = dataSet + ".event.raw.root";
-    monFile = dataSet + ".event.raw.moni.root";
-  }
+  // -----   Full file names   ----------------------------------------------
+  if (inputEvents.IsNull()) inputEvents = "test";
+  TString evntFile = inputEvents + ".tra.root";
+  TString signFile = inputSignal + ".tra.root";
+  TString beamFile = inputBeam + ".tra.root";
+  TString parFile  = inputEvents + ".par.root";
+  if (output.IsNull()) output = inputEvents;
+  TString outFile  = output + ".raw.root";
+  TString moniFile = output + ".moni_digi.root";
+  // ------------------------------------------------------------------------
+
 
   // -----   Timer   --------------------------------------------------------
   TStopwatch timer;
@@ -78,18 +106,47 @@ void run_digi(Int_t nEvents            = 2,       // Number of events to process
   // ------------------------------------------------------------------------
 
 
+  // -----  Catch event-by-event case   -------------------------------------
+  // Mixing different inputs does not make sense in event-by-event.
+  // Embedding event-by-event is not yet possible (will change soon).
+  Bool_t eventMode = eventRate < 0.;
+  if (eventMode) {
+    if (!inputSignal.IsNull()) {
+      std::cout << std::endl;
+      std::cout << "-E- " << myName
+                << ": Embedding is not (yet) possible in event-by-event mode! "
+                << " Terminating macro execution." << std::endl;
+      return;
+    }  //? Signal input specified
+    if (!inputBeam.IsNull()) {
+      std::cout << std::endl;
+      std::cout << "-E- " << myName
+                << ": Mixing inputs is not possible in event-by-event mode! "
+                << " Terminating macro execution." << std::endl;
+      return;
+    }  //? Beam input specified
+  }    //? Event-by-event mode
+  // ------------------------------------------------------------------------
+
+
   // -----   Digitization run   ---------------------------------------------
   CbmDigitization run;
-
-  run.AddInput(inFile, eventRate);
+  run.AddInput(0, evntFile, eventRate);
+  if (!eventMode) {
+    if (!inputSignal.IsNull()) run.EmbedInput(1, signFile, 0);
+    if (!inputBeam.IsNull())
+      run.AddInput(2, beamFile, beamRate, ECbmTreeAccess::kRandom);
+  }
   run.SetOutputFile(outFile, overwrite);
-  run.SetMonitorFile(monFile);
+  run.SetMonitorFile(moniFile);
   run.SetParameterRootFile(parFile);
-  run.SetTimeSliceLength(timeSliceLength);
+  run.SetTimeSliceLength(tsLength);
   run.SetEventMode(eventMode);
   run.SetProduceNoise(kFALSE);
-
-  run.Run(nEvents);
+  if (nEvents < 0)
+    run.Run();
+  else
+    run.Run(nEvents);
   // ------------------------------------------------------------------------
 
 
@@ -99,34 +156,17 @@ void run_digi(Int_t nEvents            = 2,       // Number of events to process
   Double_t ctime = timer.CpuTime();
   std::cout << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFile << std::endl;
   std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
-            << std::endl
             << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   CTest resource monitoring   ------------------------------------
   FairSystemInfo sysInfo;
   Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-  std::cout << "<DartMeasurement name=\"WallTime\" type=\"numeric/double\">";
-  std::cout << rtime;
-  std::cout << "</DartMeasurement>" << std::endl;
+  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"
+            << maxMemory << "</DartMeasurement>" << std::endl;
+  std::cout << "<DartMeasurement name=\"WallTime\" type=\"numeric/double\">"
+            << rtime << "</DartMeasurement>" << std::endl;
   Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
+  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"
+            << cpuUsage << "</DartMeasurement>" << std::endl;
   // ------------------------------------------------------------------------
 
-
-  // -----   Finish   -------------------------------------------------------
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
-  // ------------------------------------------------------------------------
-
-
 }  // End of macro
diff --git a/macro/run/run_reco.C b/macro/run/run_reco.C
new file mode 100644
index 0000000000..c642f66a6c
--- /dev/null
+++ b/macro/run/run_reco.C
@@ -0,0 +1,484 @@
+/** @file run_reco.C
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since 14 November 2020
+ **/
+
+
+// --- Includes needed for IDE
+#if !defined(__CLING__)
+#include "CbmBuildEventsFromTracksReal.h"
+#include "CbmBuildEventsIdeal.h"
+#include "CbmDefs.h"
+#include "CbmFindPrimaryVertex.h"
+#include "CbmKF.h"
+#include "CbmL1.h"
+#include "CbmL1StsTrackFinder.h"
+#include "CbmLitFindGlobalTracks.h"
+#include "CbmMuchFindHitsGem.h"
+#include "CbmMvdClusterfinder.h"
+#include "CbmMvdHitfinder.h"
+#include "CbmPVFinderKF.h"
+#include "CbmPrimaryVertexFinder.h"
+#include "CbmPsdHitProducer.h"
+#include "CbmRecoSts.h"
+#include "CbmRichHitProducer.h"
+#include "CbmRichReconstruction.h"
+#include "CbmSetup.h"
+#include "CbmStsFindTracks.h"
+#include "CbmStsFindTracksEvents.h"
+#include "CbmStsTrackFinder.h"
+#include "CbmTofSimpClusterizer.h"
+#include "CbmTrdClusterFinder.h"
+#include "CbmTrdHitProducer.h"
+#include <FairFileSource.h>
+#include <FairMonitor.h>
+#include <FairParAsciiFileIo.h>
+#include <FairParRootFileIo.h>
+#include <FairRunAna.h>
+#include <FairRuntimeDb.h>
+#include <FairSystemInfo.h>
+#include <TStopwatch.h>
+#endif
+
+
+/** @brief Macro for CBM reconstruction
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since  14 November 2020
+ ** @param input          Name of input file (w/o extension .raw.root)
+ ** @param nTimeSlices    Number of time-slices to process
+ ** @param firstTimeSlice First time-slice (entry) to be processed
+ ** @param output         Name of output file (w/o extension .rec.root)
+ ** @param evBuildRaw     Option for raw event building
+ ** @param setup          Name of predefined geometry setup
+ ** @param paramFile      Parameter ROOT file (w/o extension .par.root)
+ **
+ ** This macro performs from the digis in a time-slice. It can be used
+ ** for simulated data (result of run_digi.C) or real data after unpacking.
+ **
+ ** The macro covers both time-based reconstruction and event-based
+ ** reconstruction using raw events build from digis. This can be selected
+ ** by the forth argument. If left empty, no raw event builder will be
+ ** employed and reconstruction will be time-based. The option "Ideal"
+ ** selects the ideal raw event builder, which associates digis to events
+ ** based on the MC truth. The option "Real" selects a real raw event builder
+ ** (not yet available).
+ **
+ ** The file names must be specified without extensions. The convention is
+ ** that the raw (input) file is [input].raw.root. The output file
+ ** will be [input].rec.root if not specified by the user. The parameter file
+ ** has the extension .par.root. It is assumed to be [input].par.root if
+ ** not specified by the user.
+ **
+ ** If no argument is specified, the input will be set to "test". This allows
+ ** to execute the macro chain (run_tra_file.C, run_digi.C and run_reco.C)
+ ** from the ROOT prompt without user intervention.
+ **
+ **/
+void run_reco(TString input        = "",
+              Int_t nTimeSlices    = -1,
+              Int_t firstTimeSlice = 0,
+              TString output       = "",
+              TString evBuildRaw   = "",
+              TString setup        = "sis100_electron",
+              TString paramFile    = "") {
+
+  // ========================================================================
+  //          Adjust this part according to your requirements
+
+  // --- Logger settings ----------------------------------------------------
+  TString logLevel     = "INFO";
+  TString logVerbosity = "LOW";
+  // ------------------------------------------------------------------------
+
+
+  // -----   Environment   --------------------------------------------------
+  TString myName = "run_reco";  // this macro's name for screen output
+  TString srcDir = gSystem->Getenv("VMCWORKDIR");  // top source directory
+  // ------------------------------------------------------------------------
+
+
+  // -----   In- and output file names   ------------------------------------
+  if (input.IsNull()) input = "test";
+  TString rawFile = input + ".raw.root";
+  TString outFile = input + ".rec.root";
+  TString monFile = input + ".moni_reco.root";
+  if (output.IsNull()) output = input;
+  outFile = output + ".reco.root";
+  monFile = output + ".moni_reco.root";
+  if (paramFile.IsNull()) paramFile = input;
+  TString parFile = paramFile + ".par.root";
+  std::cout << "Inputfile " << rawFile << std::endl;
+  std::cout << "Outfile " << outFile << std::endl;
+  std::cout << "Parfile " << parFile << std::endl;
+
+  // ------------------------------------------------------------------------
+
+
+  // -----   Load the geometry setup   -------------------------------------
+  std::cout << std::endl;
+  std::cout << "-I- " << myName << ": Loading setup " << setup << std::endl;
+  CbmSetup* geo = CbmSetup::Instance();
+  geo->LoadSetup(setup);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Some global switches   -----------------------------------------
+  Bool_t eventBased = !evBuildRaw.IsNull();
+  Bool_t useMvd     = geo->IsActive(ECbmModuleId::kMvd);
+  Bool_t useSts     = geo->IsActive(ECbmModuleId::kSts);
+  Bool_t useRich    = geo->IsActive(ECbmModuleId::kRich);
+  Bool_t useMuch    = geo->IsActive(ECbmModuleId::kMuch);
+  Bool_t useTrd     = geo->IsActive(ECbmModuleId::kTrd);
+  Bool_t useTof     = geo->IsActive(ECbmModuleId::kTof);
+  Bool_t usePsd     = geo->IsActive(ECbmModuleId::kPsd);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Parameter files as input to the runtime database   -------------
+  std::cout << std::endl;
+  std::cout << "-I- " << myName << ": Defining parameter files " << std::endl;
+  TList* parFileList = new TList();
+  TString geoTag;
+
+  // - TRD digitisation parameters
+  if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTrd, geoTag)) {
+    const Char_t* npar[4] = {"asic", "digi", "gas", "gain"};
+    TObjString* trdParFile(NULL);
+    for (Int_t i(0); i < 4; i++) {
+      trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "."
+                                  + npar[i] + ".par");
+      parFileList->Add(trdParFile);
+      std::cout << "-I- " << myName << ": Using parameter file "
+                << trdParFile->GetString() << std::endl;
+    }
+  }
+
+  // - TOF digitisation parameters
+  if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTof, geoTag)) {
+    TObjString* tofFile =
+      new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digi.par");
+    parFileList->Add(tofFile);
+    std::cout << "-I- " << myName << ": Using parameter file "
+              << tofFile->GetString() << std::endl;
+    TObjString* tofBdfFile =
+      new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par");
+    parFileList->Add(tofBdfFile);
+    std::cout << "-I- " << myName << ": Using parameter file "
+              << tofBdfFile->GetString() << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+  // In general, the following parts need not be touched
+  // ========================================================================
+
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+  timer.Start();
+  // ------------------------------------------------------------------------
+
+
+  // -----   FairRunAna   ---------------------------------------------------
+  FairRunAna* run             = new FairRunAna();
+  FairFileSource* inputSource = new FairFileSource(rawFile);
+  run->SetSource(inputSource);
+  run->SetOutputFile(outFile);
+  run->SetGenerateRunInfo(kTRUE);
+  FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monFile);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Logger settings   ----------------------------------------------
+  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
+  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
+  // ------------------------------------------------------------------------
+
+
+  // -----   Raw event building from digis   --------------------------------
+  if (eventBased) {
+    if (evBuildRaw.EqualTo("Ideal", TString::ECaseCompare::kIgnoreCase)) {
+      FairTask* evBuildRaw = new CbmBuildEventsIdeal();
+      run->AddTask(evBuildRaw);
+      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName()
+                << std::endl;
+      eventBased = kTRUE;
+    }  //? Ideal raw event building
+    else if (evBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) {
+      std::cerr << "-E- " << myName
+                << ": Real event building is not yet available! "
+                << "Terminating macro execution." << std::endl;
+      return;
+    }  //? Real raw event building
+    else {
+      std::cerr << "-E- " << myName << ": Unknown option " << evBuildRaw
+                << " for raw event building! Terminating macro execution."
+                << std::endl;
+      return;
+    }
+  }  //? event-based reco
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in MVD   ----------------------------------
+  if (useMvd) {
+
+    CbmMvdClusterfinder* mvdCluster =
+      new CbmMvdClusterfinder("MVD Cluster Finder", 0, 0);
+    run->AddTask(mvdCluster);
+    std::cout << "-I- : Added task " << mvdCluster->GetName() << std::endl;
+
+    CbmMvdHitfinder* mvdHit = new CbmMvdHitfinder("MVD Hit Finder", 0, 0);
+    mvdHit->UseClusterfinder(kTRUE);
+    run->AddTask(mvdHit);
+    std::cout << "-I- " << myName << ": Added task " << mvdHit->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in STS   ----------------------------------
+  if (useSts) {
+    CbmRecoSts* stsReco = new CbmRecoSts(kCbmRecoTimeslice);
+    if (eventBased) stsReco->SetMode(kCbmRecoEvent);
+    run->AddTask(stsReco);
+    std::cout << "-I- " << myName << ": Added task " << stsReco->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in RICH   ---------------------------------
+  if (useRich) {
+    CbmRichHitProducer* richHitProd = new CbmRichHitProducer();
+    run->AddTask(richHitProd);
+    std::cout << "-I- " << myName << ": Added task " << richHitProd->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in MUCH   ---------------------------------
+  if (useMuch) {
+
+    // --- Parameter file name
+    TString geoTag;
+    geo->GetGeoTag(ECbmModuleId::kMuch, geoTag);
+    Int_t muchFlag  = (geoTag.Contains("mcbm") ? 0 : 1);
+    TString parFile = gSystem->Getenv("VMCWORKDIR");
+    parFile += "/parameters/much/much_" + geoTag(0, 4) + "_digi_sector.root";
+    std::cout << "Using parameter file " << parFile << std::endl;
+
+    // --- Hit finder for GEMs
+    FairTask* muchReco = new CbmMuchFindHitsGem(parFile.Data(), muchFlag);
+    run->AddTask(muchReco);
+    std::cout << "-I- " << myName << ": Added task " << muchReco->GetName()
+              << " with parameter file " << parFile << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in TRD   ----------------------------------
+  if (useTrd) {
+
+    Double_t triggerThreshold       = 0.5e-6;  // SIS100
+    CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
+    if (eventBased)
+      trdCluster->SetTimeBased(kFALSE);
+    else
+      trdCluster->SetTimeBased(kTRUE);
+    trdCluster->SetNeighbourEnable(true, false);
+    trdCluster->SetMinimumChargeTH(triggerThreshold);
+    trdCluster->SetRowMerger(true);
+    run->AddTask(trdCluster);
+    std::cout << "-I- " << myName << ": Added task " << trdCluster->GetName()
+              << std::endl;
+
+    CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
+    run->AddTask(trdHit);
+    std::cout << "-I- " << myName << ": Added task " << trdHit->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in TOF   ----------------------------------
+  if (useTof) {
+    CbmTofSimpClusterizer* tofCluster =
+      new CbmTofSimpClusterizer("TOF Simple Clusterizer", 0);
+    tofCluster->SetOutputBranchPersistent("TofHit", kTRUE);
+    tofCluster->SetOutputBranchPersistent("TofDigiMatch", kTRUE);
+    run->AddTask(tofCluster);
+    std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Local reconstruction in PSD   ----------------------------------
+  if (usePsd) {
+    CbmPsdHitProducer* psdHit = new CbmPsdHitProducer();
+    run->AddTask(psdHit);
+    std::cout << "-I- " << myName << ": Added task " << psdHit->GetName()
+              << std::endl;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Track finding in STS (+ MVD)    --------------------------------
+  if (useMvd || useSts) {
+    CbmKF* kalman = new CbmKF();
+    run->AddTask(kalman);
+    CbmL1* l1 = new CbmL1("L1", 0);
+
+    // --- Material budget file names
+    TString mvdGeoTag;
+    if (geo->GetGeoTag(ECbmModuleId::kMvd, mvdGeoTag)) {
+      TString parFile = gSystem->Getenv("VMCWORKDIR");
+      parFile += "/parameters/mvd/mvd_matbudget_" + mvdGeoTag + ".root";
+      std::cout << "Using material budget file " << parFile << std::endl;
+      l1->SetMvdMaterialBudgetFileName(parFile.Data());
+    }
+    TString stsGeoTag;
+    if (geo->GetGeoTag(ECbmModuleId::kSts, stsGeoTag)) {
+      TString parFile = gSystem->Getenv("VMCWORKDIR");
+      parFile += "/parameters/sts/sts_matbudget_" + stsGeoTag + ".root";
+      std::cout << "Using material budget file " << parFile << std::endl;
+      l1->SetStsMaterialBudgetFileName(parFile.Data());
+    }
+    run->AddTask(l1);
+    std::cout << "-I- " << myName << ": Added task " << l1->GetName()
+              << std::endl;
+
+    CbmStsTrackFinder* stsTrackFinder = new CbmL1StsTrackFinder();
+    if (eventBased) {
+      FairTask* stsFindTracks =
+        new CbmStsFindTracksEvents(stsTrackFinder, useMvd);
+      run->AddTask(stsFindTracks);
+      std::cout << "-I- " << myName << ": Added task "
+                << stsFindTracks->GetName() << std::endl;
+    } else {
+      FairTask* stsFindTracks = new CbmStsFindTracks(0, stsTrackFinder, useMvd);
+      run->AddTask(stsFindTracks);
+      std::cout << "-I- " << myName << ": Added task "
+                << stsFindTracks->GetName() << std::endl;
+    }
+  }
+  // ------------------------------------------------------------------------
+
+
+  // ==== From here on, the time-based and the event-based reconstruction
+  // ==== chains differ, since time-based version of primary vertex finding
+  // ==== and global tracking are not yet available. For time-based
+  // ==== reconstruction, a track-based event finder is used; no global
+  // ==== tracks are produced.
+
+  if (eventBased) {
+
+    // -----   Primary vertex finding   -------------------------------------
+    CbmPrimaryVertexFinder* pvFinder = new CbmPVFinderKF();
+    CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder);
+    run->AddTask(findVertex);
+    std::cout << "-I- " << myName << ": Added task " << findVertex->GetName()
+              << std::endl;
+    // ----------------------------------------------------------------------
+
+
+    // ---   Global track finding   -----------------------------------------
+    CbmLitFindGlobalTracks* finder = new CbmLitFindGlobalTracks();
+    finder->SetTrackingType("branch");
+    finder->SetMergerType("nearest_hit");
+    run->AddTask(finder);
+    std::cout << "-I- : Added task " << finder->GetName() << std::endl;
+    // ----------------------------------------------------------------------
+
+
+    // -----   RICH reconstruction   ----------------------------------------
+    if (useRich) {
+      CbmRichReconstruction* richReco = new CbmRichReconstruction();
+      run->AddTask(richReco);
+      std::cout << "-I- : Added task " << richReco->GetName() << std::endl;
+    }
+    // ----------------------------------------------------------------------
+
+  }  //? event-based reco
+
+  else {
+
+    // -----   Event building from STS tracks   -----------------------------
+    run->AddTask(new CbmBuildEventsFromTracksReal());
+    // ----------------------------------------------------------------------
+
+  }  //? time-based reco
+
+
+  // -----  Parameter database   --------------------------------------------
+  std::cout << std::endl << std::endl;
+  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
+  FairRuntimeDb* rtdb        = run->GetRuntimeDb();
+  FairParRootFileIo* parIo1  = new FairParRootFileIo();
+  FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
+  parIo1->open(parFile.Data(), "UPDATE");
+  rtdb->setFirstInput(parIo1);
+  if (!parFileList->IsEmpty()) {
+    parIo2->open(parFileList, "in");
+    rtdb->setSecondInput(parIo2);
+  }
+  // ------------------------------------------------------------------------
+
+
+  // -----   Run initialisation   -------------------------------------------
+  std::cout << std::endl;
+  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
+  run->Init();
+  rtdb->setOutput(parIo1);
+  rtdb->saveOutput();
+  rtdb->print();
+  // ------------------------------------------------------------------------
+
+
+  // -----   Register light ions (d, t, He3, He4)   -------------------------
+  std::cout << std::endl;
+  TString registerLightIonsMacro = gSystem->Getenv("VMCWORKDIR");
+  registerLightIonsMacro += "/macro/KF/registerLightIons.C";
+  std::cout << "Loading macro " << registerLightIonsMacro << std::endl;
+  gROOT->LoadMacro(registerLightIonsMacro);
+  gROOT->ProcessLine("registerLightIons()");
+  // ------------------------------------------------------------------------
+
+
+  // -----   Start run   ----------------------------------------------------
+  std::cout << std::endl << std::endl;
+  std::cout << "-I- " << myName << ": Starting run" << std::endl;
+  run->Run(firstTimeSlice, nTimeSlices);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Finish   -------------------------------------------------------
+  timer.Stop();
+  FairMonitor::GetMonitor()->Print();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  std::cout << std::endl << std::endl;
+  std::cout << "Macro finished successfully." << std::endl;
+  std::cout << "Output file is    " << outFile << std::endl;
+  std::cout << "Parameter file is " << parFile << std::endl;
+  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
+            << std::endl;
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  std::cout << maxMemory;
+  std::cout << "</DartMeasurement>" << std::endl;
+  Float_t cpuUsage = ctime / rtime;
+  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  std::cout << cpuUsage;
+  std::cout << "</DartMeasurement>" << std::endl;
+  // ------------------------------------------------------------------------
+
+
+  // -----   This is to prevent a malloc error when exiting ROOT   ----------
+  // The source of the error is unknown. Related to TGeoManager.
+  RemoveGeoManager();
+  // ------------------------------------------------------------------------
+
+}  // End of main macro function
diff --git a/macro/run/run_tra_beam.C b/macro/run/run_tra_beam.C
new file mode 100644
index 0000000000..ba73a8c809
--- /dev/null
+++ b/macro/run/run_tra_beam.C
@@ -0,0 +1,176 @@
+/** @file run_tra_beam.C
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since 3 November 2020
+ **/
+
+// Includes needed for IDE
+#if !defined(__CLING__)
+#include "CbmBeamGenerator.h";
+#include "CbmTransport.h"
+#include "FairSystemInfo.h"
+#include "TStopwatch.h"
+#endif
+
+/** @brief Macro for transport simulation of beam particles through CBM
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since  3 November 2020
+ ** @param nEvents    Number of beam particles to simulate (one per event)
+ ** @param species    Beam ion species, e.g. "C" or "Au"
+ ** @param beamP      Beam momentum per nucleon [GeV]
+ ** @param beamStartZ Start z coordinate of beam
+ ** @param output     Name of output data set
+ ** @param setup      Name of predefined geometry setup
+ ** @param engine     kGeant3 or kGeant4
+ **
+ ** This macro performs the transport simulation of beam particles
+ ** through the CBM setup using the CbmBeamGenerator class. The macro
+ ** demonstrates the minimal settings needed to perform this transport:
+ ** number of events, beam species, beam momentum, start position of the beam,
+ ** output file names, geometry setup and the transport engine. These can be
+ ** specified through the arguments. Also for the arguments, defaults are
+ ** defined, such that the macro should execute from scratch with no arguments.
+ **
+ ** The following output files are generated:
+ ** - [output].tra.root:  Output MC data (MCPoints and MCTracks)
+ ** - [output].par.root:  Parameter file with e.g. the geometry and field in
+ ** - [output].geo.root:  Used geometry in TGeoManager format
+ **
+ ** [setup]: specifies the geometry setup to be used in the
+ ** transport run. This has to be chosen from the available predefined
+ ** setups (see the folder geometry/setup). By default, the setup
+ ** sis100_electron will be used.
+ **
+ ** [engine]: transport engine. The user can choose between GEANT3 (default)
+ ** and GEANT4.
+ **
+ ** Some other required definitions are coded in the macro body:
+ ** the target properties and the beam profile. A beam trajectory is sampled
+ ** for each event from the specified beam profile.
+ **
+ ** All other settings are the default ones in the steering class
+ ** CbmTransport. For the options, consult the documentation of that class:
+ ** http://computing.gitpages.cbm.gsi.de/cbmroot/classCbmTransport.html
+ **/
+void run_tra_beam(Int_t nEvents       = 1,
+                  const char* species = "Au",
+                  Double_t beamP      = 12.,
+                  Double_t beamStartZ = -1.,
+                  const char* output  = "beam",
+                  const char* setup   = "sis100_electron",
+                  ECbmEngine engine   = kGeant3) {
+
+  // --- Logger settings ----------------------------------------------------
+  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
+  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
+  // ------------------------------------------------------------------------
+
+
+  // -----   Environment   --------------------------------------------------
+  TString myName = "run_tra_beam";  // this macro's name for screen output
+  TString srcDir = gSystem->Getenv("VMCWORKDIR");  // top source directory
+  // ------------------------------------------------------------------------
+
+
+  // -----   File names   ---------------------------------------------------
+  TString dataset(output);
+  TString outFile = dataset + ".tra.root";
+  TString parFile = dataset + ".par.root";
+  TString geoFile = dataset + ".geo.root";
+  // ------------------------------------------------------------------------
+
+
+  // ----   Define the beam   -----------------------------------------------
+  // Here, the most frequent CBM beams are pre-defined. If you want another
+  // beam species, add to this list.
+  UInt_t beamZ = 0;
+  UInt_t beamA = 0;
+  UInt_t beamQ = 0;
+  if (TString(species).EqualTo("H", TString::kIgnoreCase)) {
+    beamZ = 1;  // atomic number
+    beamA = 1;  // mass number
+    beamQ = 1;  // charge (fully stripped)
+  } else if (TString(species).EqualTo("C", TString::kIgnoreCase)) {
+    beamZ = 6;   // atomic number
+    beamA = 12;  // mass number
+    beamQ = 6;   // charge (fully stripped)
+  } else if (TString(species).EqualTo("Ca", TString::kIgnoreCase)) {
+    beamZ = 20;  // atomic number
+    beamA = 40;  // mass number
+    beamQ = 20;  // charge (fully stripped)
+  } else if (TString(species).EqualTo("Ni", TString::kIgnoreCase)) {
+    beamZ = 28;  // atomic number
+    beamA = 60;  // mass number
+    beamQ = 28;  // charge (fully stripped)
+  } else if (TString(species).EqualTo("Ag", TString::kIgnoreCase)) {
+    beamZ = 47;   // atomic number
+    beamA = 108;  // mass number
+    beamQ = 47;   // charge (fully stripped)
+  } else if (TString(species).EqualTo("Au", TString::kIgnoreCase)) {
+    beamZ = 79;   // atomic number
+    beamA = 197;  // mass number
+    beamQ = 79;   // charge (fully stripped)
+  }
+  if (beamZ == 0) {
+    std::cout << "-E- " << myName << ": unknown beam species " << species
+              << std::endl;
+    return;
+  }
+  // ------------------------------------------------------------------------
+
+
+  // ----   Define the beam profile   ---------------------------------------
+  Double_t beamFocusZ  = 0.;     // z coordinate of beam focal plane
+  Double_t beamMeanX   = 0.;     // mean x position of beam [cm]
+  Double_t beamSigmaX  = 0.1;    // Gaussian sigma of beam x position [cm]
+  Double_t beamMeanY   = 0.;     // mean y position of beam [cm]
+  Double_t beamSigmaY  = 0.1;    // Gaussian sigma of beam y position [cm]
+  Double_t beamMeanTx  = 0.;     // mean x-z angle of beam [rad]
+  Double_t beamSigmaTx = 0.001;  // Gaussian sigma of beam x-z angle [rad]
+  Double_t beamMeanTy  = 0.;     // mean x-y angle of beam [rad]
+  Double_t beamSigmaTy = 0.001;  // Gaussian sigma of beam x-y angle [rad]
+  // ------------------------------------------------------------------------
+
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+  timer.Start();
+  // ------------------------------------------------------------------------
+
+
+  // --- Transport run   ----------------------------------------------------
+  CbmTransport run;
+  run.SetEngine(engine);
+  run.SetOutFileName(outFile);
+  run.SetParFileName(parFile);
+  run.SetGeoFileName(geoFile);
+  run.LoadSetup(setup);
+  run.SetTarget("Gold", 0.025, 2.5);
+  run.SetBeamPosition(beamMeanX, beamMeanY, beamSigmaX, beamSigmaY, beamFocusZ);
+  run.SetBeamAngle(beamMeanTx, beamMeanTy, beamSigmaTx, beamSigmaTy);
+  run.AddInput(new CbmBeamGenerator(beamZ, beamA, beamQ, beamP, beamStartZ));
+  run.Run(nEvents);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Finish   -------------------------------------------------------
+  timer.Stop();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  std::cout << "Macro finished successfully." << std::endl;
+  std::cout << "Real time " << rtime << " s, CPU time " << ctime << "s"
+            << std::endl
+            << std::endl;
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  std::cout << maxMemory;
+  std::cout << "</DartMeasurement>" << std::endl;
+  Float_t cpuUsage = ctime / rtime;
+  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  std::cout << cpuUsage;
+  std::cout << "</DartMeasurement>" << std::endl;
+  std::cout << " Test passed" << std::endl;
+  std::cout << " All ok " << std::endl;
+  // ------------------------------------------------------------------------
+
+}  // End of macro
diff --git a/macro/run/run_tra_file.C b/macro/run/run_tra_file.C
new file mode 100644
index 0000000000..95588c604a
--- /dev/null
+++ b/macro/run/run_tra_file.C
@@ -0,0 +1,175 @@
+/** @file run_tra_file.C
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since 3 November 2020
+ **/
+
+// Includes needed for IDE
+#if !defined(__CLING__)
+#include "CbmTransport.h"
+#include "FairSystemInfo.h"
+#include "TStopwatch.h"
+#endif
+
+
+/** @brief Macro for transport simulation of events from file
+ ** @author Volker Friese <v.friese@gsi.de>
+ ** @since  3 November 2020
+ ** @param input      Name of input file
+ ** @param nEvents    Number of events to transport
+ ** @param output     Name of output data set
+ ** @param setup      Name of predefined geometry setup
+ ** @param engine     kGeant3 or kGeant4
+ **
+ ** This macro performs the transport simulation of externally generated
+ ** events from an input file. The macro demonstrates the minimal settings
+ ** needed to perform the transport: input and output file names,
+ ** geometry setup, number of events and the transport engine. These can be
+ ** specified through the arguments. Also for the arguments, defaults are
+ ** defined, such that the macro should execute from scratch with no arguments.
+ **
+ ** First argument [input]: input file name. If left empty, a default input
+ ** file (urqmd) distributed with cbmroot will be used. If the file name
+ ** starts with "pluto", CbmPlutoGenerator will be used, otherwise
+ ** the input is assumed to be in unigen format. Other file formats require
+ ** intervention into the macro code.
+ **
+ ** Second argument: [nEvents]: Number of events to be processed.
+ **
+ ** Third argument [output]: specifies the names of the output files:
+ ** - [output].tra.root:  Output MC data (MCPoints and MCTracks)
+ ** - [output].par.root:  Parameter file with e.g. the geometry and field in
+ ** - [output].geo.root:  Used geometry in TGeoManager format
+ ** If left empty, the term "test" will be used.
+ **
+ ** Fourth argument [setup]: specifies the geometry setup to be used in the
+ ** transport run. This has to be chosen from the available predefined
+ ** setups (see the folder geometry/setup). By default, the setup
+ ** sis100_electron will be used.
+ **
+ ** Fifth argument [engine]: transport engine. The user can choose between
+ ** GEANT3 (default) and GEANT4.
+ **
+ ** Some other required definitions are coded in the macro body:
+ ** the target properties and the beam profile. The event vertex will be
+ ** sampled along the intersection of the beam trajectory with the target
+ ** volume. A beam trajectory is sampled for each event from the specified
+ ** beam profile. The beam angle is zero. Random rotation of the event
+ ** plane around the z axis is activated.
+ **
+ ** All other settings are the default ones in the steering class
+ ** CbmTransport. For the options, consult the documentation of that class:
+ ** http://computing.gitpages.cbm.gsi.de/cbmroot/classCbmTransport.html
+ **/
+void run_tra_file(const char* input  = "",
+                  Int_t nEvents      = 1,
+                  const char* output = "",
+                  const char* setup  = "sis100_electron",
+                  ECbmEngine engine  = kGeant3) {
+
+  // --- Logger settings ----------------------------------------------------
+  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
+  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
+  // ------------------------------------------------------------------------
+
+
+  // -----   Environment   --------------------------------------------------
+  TString myName = "run_tra_file";  // this macro's name for screen output
+  TString srcDir = gSystem->Getenv("VMCWORKDIR");  // top source directory
+  // ------------------------------------------------------------------------
+
+
+  // -----   Input file   ---------------------------------------------------
+  // Use default input if not specified by the user
+  TString defaultInput = srcDir + "/input/urqmd.auau.10gev.centr.root";
+  TString inFile = (strcmp(input, "") == 0 ? defaultInput : TString(input));
+  std::cout << "-I- " << myName << ": Using input file " << inFile << std::endl;
+  // ------------------------------------------------------------------------
+
+
+  // -----   Output files   -------------------------------------------------
+  TString dataset(output);
+  if (dataset.IsNull()) dataset = "test";
+  TString outFile = dataset + ".tra.root";
+  TString parFile = dataset + ".par.root";
+  TString geoFile = dataset + ".geo.root";
+  std::cout << std::endl;
+  // ------------------------------------------------------------------------
+
+
+  // -----   Target properties   --------------------------------------------
+  // For flexibility, the target volume is not part of the predefined
+  // geometry setup. It thus has to be specified in this macro. By default,
+  // a Gold target of 250 micrometer thickness and 2.5 cm diameter is used.
+  const char* targetMedium = "Gold";
+  Double_t targetThickness = 0.025;  // in cm
+  Double_t targetDiameter  = 2.5;    // in cm
+  // ------------------------------------------------------------------------
+
+
+  // -----   Beam properties   ----------------------------------------------
+  // The beam particles themselves are not subject to the transport,
+  // but the properties of the beam determine where the main collision
+  // vertex is placed and how the event is rotated. The collision vertex
+  // is determined from the intersection of the beam through the target.
+  // The beam defined here is along the z axis and its distributions in
+  // (x,y) are Gaussian with mean values 0 and sigma 1 mm.
+  Double_t beamPosX   = 0.;
+  Double_t beamPosY   = 0.;
+  Double_t beamSigmaX = 0.1;  // cm
+  Double_t beamSigmaY = 0.1;  // cm
+  // ------------------------------------------------------------------------
+
+
+  // -----   Event plane rotation   -----------------------------------------
+  // Some generators, e.g., UrQMD, generate the event plane always at
+  // zero angle, i.e., the impact parameter is in the x direction. In order
+  // get a realistic distribution, the event plane has to be randomly
+  // rotated around the z axis. This changes the momentum direction of
+  // all primary particles coherently.
+  Bool_t rotateEvents = kTRUE;
+  // ------------------------------------------------------------------------
+
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+  timer.Start();
+  // ------------------------------------------------------------------------
+
+
+  // --- Transport run   ----------------------------------------------------
+  CbmTransport run;
+  run.SetEngine(engine);
+  if (inFile.Contains("pluto", TString::kIgnoreCase)) {
+    run.AddInput(inFile, kPluto);
+  } else
+    run.AddInput(inFile, kUnigen);
+  run.SetOutFileName(outFile);
+  run.SetParFileName(parFile);
+  run.SetGeoFileName(geoFile);
+  run.LoadSetup(setup);
+  run.SetTarget(targetMedium, targetThickness, targetDiameter);
+  run.SetBeamPosition(beamPosX, beamPosY, beamSigmaX, beamSigmaY);
+  if (rotateEvents) run.SetRandomEventPlane();
+  run.Run(nEvents);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Finish   -------------------------------------------------------
+  timer.Stop();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  std::cout << "Macro finished successfully." << std::endl;
+  std::cout << "Real time " << rtime << " s, CPU time " << ctime << "s"
+            << std::endl;
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  std::cout << maxMemory;
+  std::cout << "</DartMeasurement>" << std::endl;
+  Float_t cpuUsage = ctime / rtime;
+  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  std::cout << cpuUsage;
+  std::cout << "</DartMeasurement>" << std::endl;
+  // ------------------------------------------------------------------------
+
+}  // End of macro
diff --git a/macro/run/run_transport_beam.C b/macro/run/run_transport_beam.C
deleted file mode 100644
index 8a8a5c772d..0000000000
--- a/macro/run/run_transport_beam.C
+++ /dev/null
@@ -1,134 +0,0 @@
-/** @file run_transport_beam.C
- ** @author Volker Friese <v.friese@gsi.de>
- ** @since 9 September 2020
- **/
-
-// Includes needed for IDE
-#if !defined(__CLING__)
-#include "CbmBeamGenerator";
-#include "CbmTransport.h"
-#include "FairSystemInfo.h"
-#include "TStopwatch.h"
-#endif
-
-
-/** @brief run_transport_beam
- ** @author Volker Friese <v.friese@gsi.de>
- ** @since  9 September 2020
- ** @param nEvents    Number of events from input to transport
- ** @param setupName  Name of predefined geometry setup
- ** @param output     Name of output data set
- ** @param inputFile  Name of input file
- **
- ** Macro for transport simulation of beam particles in the CBM setup.
- ** Properties of the beam have to be specified in the macro body.
- **
- ** For the setup (geometry and field), predefined setups can be chosen
- ** by the second argument. Available setups are in geometry/setup.
- **
- ** The output file will be named [output].tra.root.
- ** A parameter file [output].par.root will be created.
- ** The geometry (TGeoManager) will be written into [output].geo.root.
- **
- ** For the options for the transport simulation, see the documentation of
- ** CbmTransport.
- **/
-void run_transport_beam(Int_t nEvents         = 1000,
-                        const char* setupName = "sis100_electron",
-                        const char* output    = "beam") {
-
-  // --- Logger settings ----------------------------------------------------
-  FairLogger::GetLogger()->SetLogScreenLevel("INFO");
-  FairLogger::GetLogger()->SetLogVerbosityLevel("LOW");
-  // ------------------------------------------------------------------------
-
-
-  // -----   Environment   --------------------------------------------------
-  TString myName = "run_transport_beam";  // this macro's name for screen output
-  TString srcDir = gSystem->Getenv("VMCWORKDIR");  // top source directory
-  // ------------------------------------------------------------------------
-
-
-  // -----   File names   ---------------------------------------------------
-  TString dataset(output);
-  TString outFile = dataset + ".tra.root";
-  TString parFile = dataset + ".par.root";
-  TString geoFile = dataset + ".geo.root";
-  // ------------------------------------------------------------------------
-
-
-  // ----   Define the beam   -----------------------------------------------
-  // Beam species here is full stripped Gold
-  UInt_t beamZ        = 79;   // atomic number
-  UInt_t beamA        = 197;  // mass number
-  UInt_t beamQ        = 79;   // charge (fully stripped)
-  Double_t beamP      = 12.;  // Momentum 12 GeV per nucleon
-  Double_t beamStartZ = -1.;  // Starts at z = -1 cm
-  // ------------------------------------------------------------------------
-
-
-  // ----   Define the beam profile   ---------------------------------------
-  Double_t beamFocusZ  = 0.;   // z coordinate of beam focal plane
-  Double_t beamMeanX   = 0.;   // mean x position of beam [cm]
-  Double_t beamSigmaX  = 0.1;  // Gaussian sigma of beam x position [cm]
-  Double_t beamMeanY   = 0.;   // mean y position of beam [cm]
-  Double_t beamSigmaY  = 0.1;  // Gaussian sigma of beam y position [cm]
-  Double_t beamMeanTx  = 0.;   // mean x-z angle of beam [rad]
-  Double_t beamSigmaTx = 1.;   // Gaussian sigma of beam x-z angle [rad]
-  Double_t beamMeanTy  = 0.;   // mean x-y angle of beam [rad]
-  Double_t beamSigmaTy = 1.;   // Gaussian sigma of beam x-y angle [rad]
-  // ------------------------------------------------------------------------
-
-
-  // -----   Timer   --------------------------------------------------------
-  TStopwatch timer;
-  timer.Start();
-  // ------------------------------------------------------------------------
-
-
-  // --- Transport run   ----------------------------------------------------
-  CbmTransport run;
-  run.SetOutFileName(outFile);
-  run.SetParFileName(parFile);
-  run.SetGeoFileName(geoFile);
-  run.LoadSetup(setupName);
-  run.SetTarget("Gold", 0.025, 2.5);
-  run.SetBeamPosition(beamMeanX, beamMeanY, beamSigmaX, beamSigmaY, beamFocusZ);
-  run.SetBeamAngle(beamMeanTx, beamMeanTy, beamSigmaTx, beamSigmaTy);
-  run.AddInput(new CbmBeamGenerator(beamZ, beamA, beamQ, beamP, beamStartZ));
-  run.Run(nEvents);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Finish   -------------------------------------------------------
-  timer.Stop();
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
-  std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFile << std::endl;
-  std::cout << "Real time " << rtime << " s, CPU time " << ctime << "s"
-            << std::endl
-            << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Resource monitoring   ------------------------------------------
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-
-  Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
-
-
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
-  // ------------------------------------------------------------------------
-
-}  // End of macro
diff --git a/reco/detectors/sts/CbmStsFindTracksEvents.cxx b/reco/detectors/sts/CbmStsFindTracksEvents.cxx
index be6da5d1f5..ad8d25f632 100644
--- a/reco/detectors/sts/CbmStsFindTracksEvents.cxx
+++ b/reco/detectors/sts/CbmStsFindTracksEvents.cxx
@@ -109,9 +109,13 @@ InitStatus CbmStsFindTracksEvents::Init() {
 
   // Array of MvdHits
   if (fUseMvd) {
-    LOG(info) << GetName() << ": including MVD hits in tracking";
     fMvdHits = (TClonesArray*) ioman->GetObject("MvdHit");
-    assert(fMvdHits);
+    if (fMvdHits == nullptr) {
+      LOG(error) << GetName()
+                 << ": Use of MVD hits selected, but no hit branch present! "
+                 << "Tracking will be done without MVD hits.";
+    } else
+      LOG(info) << GetName() << ": including MVD hits in tracking";
   }
 
   // Create and register output array for StsTracks
diff --git a/sim/transport/steer/CbmSimSteerLinkDef.h b/sim/transport/steer/CbmSimSteerLinkDef.h
index ad9db20338..51f4426add 100644
--- a/sim/transport/steer/CbmSimSteerLinkDef.h
+++ b/sim/transport/steer/CbmSimSteerLinkDef.h
@@ -10,6 +10,7 @@
 #pragma link C++ class CbmVMCSettings + ;
 #pragma link C++ class CbmGeant3Settings + ;
 #pragma link C++ class CbmGeant4Settings + ;
+#pragma link C++ enum ECbmEngine;
 
 
 #endif /* __CINT__ */
-- 
GitLab