diff --git a/graphics/VP1/VP1Algs/share/vp1 b/graphics/VP1/VP1Algs/share/vp1
index 9d167ec2ced7d46125550b7764e833ba4f2d2d0f..a002f03111787fac1c35d9912ad884f5903a203a 100755
--- a/graphics/VP1/VP1Algs/share/vp1
+++ b/graphics/VP1/VP1Algs/share/vp1
@@ -136,6 +136,7 @@ LOGFILE=""
 FILTEREVENTS=""
 FLAG_BATCH=0
 FLAG_BATCH_ALL_EVENTS=0
+FLAG_BATCH_N_EVENTS=0
 FLAG_BATCH_OUT_FOLDER=""
 FLAG_LARHV=0
 # FLAG_FULLTOROIDS=0
@@ -197,6 +198,10 @@ while [ $i -le $# ]; do
 	FLAG_HELP=1
     
     
+    ########################
+    # COMMAND-LINE OPTIONS #
+    ########################
+    
     elif [ "x${arg}" == "x-larhv" ]; then
 	FLAG_LARHV=1
   #     elif [ "x${arg}" == "x-fulltoroids" ]; then
@@ -208,46 +213,53 @@ while [ $i -le $# ]; do
 	#
 	#
 	#
-	##############
-	# BATCH MODE #
-    ##############
+	#-----------
+	# BATCH MODE 
+    #-----------
 	# check if the user provided config files with -batch/-b options
 	elif [ "x${arg}" == "x-batch" -o "x${arg}" == "x-b" ]; then 
 		if [[ "$*" == *.vp1* ]]
         then
-    		#echo "config file: YES"
 			FLAG_BATCH=1
 			# text in bold, note in bold and red. at the end we reset the text style
 			echo ""
 			echo -e "\e[1m\e[31m\e[4mNote!\e[24m You chose to run VP1 in 'batch-mode' ('${arg}').\e[39m"
-			echo -e "Thus the main VP1 window will be not shown, but in the end you will get a PNG file with the rendered image of the 3D window, based on the configuration file you provided.\e[0m"
-			echo ""
-			echo "(sleeping for 2 secs...)"
+			echo -e "Thus, the main VP1 window will be not shown, but in the end you will get a PNG file with the rendered image of the 3D window, based on the configuration file you provided.\e[0m"
 			echo ""
-			sleep 2s # to let the user read the warning message about the batch mode
 		else
-    		#echo "config file: NO"
-			ERRORS="$ERRORS\nBatch mode needs a configuration file ('.vp1')"
+			ERRORS="$ERRORS\nBatch mode needs at least one configuration file ('.vp1')"
 		fi
 	elif [ "x${arg}" == "x-batch-all-events" ]; then 
 		FLAG_BATCH_ALL_EVENTS=1
-		if [ "x$FLAG_BATCH_ALL_EVENTS" == "x1" -a "x$FLAG_BATCH" == "x0" ]; then
-    		ERRORS="$ERRORS\nOption '-batch-all-events' can't be used without '-batch'..."
-		fi
+	elif [ "x${arg}" == "x-batch-random-config" ]; then 
+		FLAG_BATCH_RANDOM_CONFIG=1
+		echo -e "\e[1m\e[31m\e[4mNote!\e[24m You chose the option 'batch-random-config' ('${arg}').\e[39m"
+		echo -e "Thus, for each event a different configuration file will be used, randomly picked from the configuration files (.vp1) you provide.\e[0m"
+		echo
 	#elif [ "x${arg}" == "x-batch-output-folder" ]; then 
 	elif [ "x${arg:0:21}" == "x-batch-output-folder=" ]; then
     	FLAG_BATCH_OUT_FOLDER=${arg:21:$((${#arg}-21))}
 	    if [ "x$FLAG_BATCH_OUT_FOLDER" == "x" ]; then
 	   	ERRORS="$ERRORS\nNeed argument to -batch-output-folder. Ex: -batch-output-folder=myFolder"
 	    fi
-    	if [ "x$FLAG_BATCH_OUT_FOLDER" != "x" -a "x$FLAG_BATCH" == "x0" ]; then
-    		ERRORS="$ERRORS\nOption '-batch-output-folder' can't be used without '-batch'..."
-    	fi
 	elif [ "x${arg:0:21}" == "x-batch-output-folder" ]; then # catch arg without '=' character
     	FLAG_BATCH_OUT_FOLDER_2=${arg:20:$((${#arg}-20))}
 	    if [ "x$FLAG_BATCH_OUT_FOLDER_2" == "x" ]; then
 	   	ERRORS="$ERRORS\nNeed argument to -batch-output-folder. Ex: -batch-output-folder=path/to/myFolder"
 	    fi
+	elif [ "x${arg:0:16}" == "x-batch-n-events=" ]; then
+	FLAG_BATCH_N_EVENTS=${arg:16:$((${#arg}-16))}
+	echo -e "\e[1m\e[31m\e[4mNote!\e[24m You chose to run VP1 in 'batch-mode' over ${FLAG_BATCH_N_EVENTS} events only. ('${arg}').\e[39m"
+	if [ "x$FLAG_BATCH_N_EVENTS" == "x" ]; then
+	    ERRORS="$ERRORS\nNeed a numeric argument to -batch-n-events"
+	else
+	    #check it is integer:
+	    echo "$FLAG_BATCH_N_EVENTS" | grep '^[0-9][0-9]*$' > /dev/null 2>&1 || \
+		ERRORS="$ERRORS\nArgument to -batch-n-events must be an integer!"
+	fi
+	#echo "(sleeping for 2 secs...)"
+	echo ""
+	sleep 2s # to let the user read the warning messages about the batch mode
 	### end of batch mode settings
 	#
 	#
@@ -393,19 +405,22 @@ while [ $i -le $# ]; do
 		LOCALEVENTSRC_AVAILDIRS[${#LOCALEVENTSRC_AVAILDIRS[@]}]="$EXTRADIR"
 	    fi
 	fi
-    
-    ###################
+
+
+ 	###################
     # VP1 CONFIG FILE #
     ###################
     elif [ ${#arg} -gt 4 -a ${arg:$((${#arg}-4)):4} == ".vp1" ]; then
 	FILES_VP1CFG[${#FILES_VP1CFG[@]}]="${arg}"
-    
+	
+	    
     #####################
     # EXTRA JOB OPTIONS #
     #####################
     elif [ ${#arg} -gt 3 -a ${arg:$((${#arg}-3)):3} == ".py" ]; then
 	FILES_EXTRAJOBOPT[${#FILES_EXTRAJOBOPT[@]}]="${arg}"
     
+    
     ########################
     # EOS / LFN INPUT DATA #
     ########################
@@ -457,6 +472,30 @@ done
 ###     SETTINGS     ###
 ########################
 
+
+# batch mode
+if [ "x$FLAG_BATCH_N_EVENTS" != "x0" -a "x$FLAG_BATCH" == "x0" ]; then
+	ERRORS="$ERRORS\nOption '-batch-n-events' can't be used without '-batch'..."
+fi
+if [ "x$FLAG_BATCH_N_EVENTS" != "x0" -a "x$FLAG_BATCH_ALL_EVENTS" == "x1" ]; then
+	ERRORS="$ERRORS\nOption '-batch-n-events' can't be used together with '-batch-all-events'... Please choose one or the other."
+fi
+if [ "x$FLAG_BATCH_ALL_EVENTS" == "x1" -a "x$FLAG_BATCH" == "x0" ]; then
+	ERRORS="$ERRORS\nOption '-batch-all-events' can't be used without '-batch'..."
+fi
+if [ "x$FLAG_BATCH_RANDOM_CONFIG" == "x1" -a "x$FLAG_BATCH" == "x0" ]; then
+	ERRORS="$ERRORS\nOption '-batch-random-config' can't be used without '-batch'..."
+fi
+if [ "x$FLAG_BATCH_RANDOM_CONFIG" == "x1" ]; then
+	echo -e "\e[1m\e[31m\e[4mNote!\e[24m You chose the option 'batch-random-config' ('${arg}').\e[39m"
+	echo -e "Thus, for each event a different configuration file will be used, randomly picked from the configuration files (.vp1) you provided:\e[0m"
+	printf "["; printf '"%s", ' "${FILES_VP1CFG[@]}"; printf "]\n"; echo
+fi
+if [ "x$FLAG_BATCH_OUT_FOLDER" != "x" -a "x$FLAG_BATCH" == "x0" ]; then
+	ERRORS="$ERRORS\nOption '-batch-output-folder' can't be used without '-batch'..."
+fi
+    	
+    			
 #live & noautoconf flags (AutoConfiguration is disabled in live and livelocal modes)
 
 if [ "x$FLAG_LIVE" == "x1" ]; then
@@ -621,8 +660,12 @@ if [ "x$FLAG_HELP" != "x0" ]; then
     echo
     echo "  -batch-all-events           : Process all events in the input data file in '-batch' mode. Use this together with '-batch'."
     echo
+    echo "  -batch-n-events=N           : Process 'N' events in the input data file in '-batch' mode. Use this together with '-batch'."
+    echo
     echo "  -batch-output-folder        : Specify an output folder to store the event displays produced with the '-batch' option."
     echo
+    echo "  -batch-random-config        : Run VP1 in 'batch' mode; for each single event a configuration file will be randomly picked out of the configuration files provided by the user. Use this together with '-batch'."
+    echo
     echo "  -larhv                      : Access current LAr HV data in the DCS_OFL database via VP1 CaloReadout system."
     echo
     echo "  -data                       : Input files are data [default assumption is simulation]. "
@@ -731,6 +774,7 @@ if [ "x$FLAG_HELP" != "x0" ]; then
     echo "liberally (when it makes sense - of course dont put e.g. both -trigdec=file.xml and -trigdec=embedded)"
     echo
     echo
+    echo "*********"
     echo "Examples:"
     echo
     echo "  * Simply run on the input files myevents1.pool.root and myevents2.pool.root"
@@ -763,7 +807,7 @@ if [ "x$FLAG_HELP" != "x0" ]; then
     echo
     echo "     \$>$APP myevents1.pool.root myconfig1.vp1 myconfig2.vp1"
     echo
-    echo "  * Run on myevents1.pool.root, and preload the tab/channel configuration files myconfig1.vp1 and myconfig2.vp1:"
+    echo "  * Run on myevents1.pool.root, and preload two tab/channel configuration files: myconfig1.vp1 and myconfig2.vp1; at start, VP1 will create multiple tabs, from the pieces of configuration information contained in both files:"
     echo
     echo "     \$>$APP myevents1.pool.root myconfig1.vp1 myconfig2.vp1"
     echo
@@ -802,7 +846,7 @@ while [ $i -le $((${#FILES_VP1CFG[@]}-1)) ]; do
     if [ "x$PYTHONFILES" == "x" ]; then
 	PYTHONFILES='vp1CfgFiles=["'"${FILES_VP1CFG[$i]}"'"'
     else
-	PYTHONFILES="${PYTHONFILES},${FILES_VP1CFG[$i]}"'"'
+	PYTHONFILES="${PYTHONFILES}"',"'"${FILES_VP1CFG[$i]}"'"'
     fi
     i=$((i+1))
 done
@@ -912,10 +956,18 @@ if [ "x$FLAG_BATCH_ALL_EVENTS" != "x0" ]; then
     if [ "x$OPTS" != "x" ]; then OPTS="$OPTS;"; fi
     OPTS="${OPTS}vp1BatchAllEvents=True"
 fi
+if [ "x$FLAG_BATCH_N_EVENTS" != "x0" ]; then
+    if [ "x$OPTS" != "x" ]; then OPTS="$OPTS;"; fi
+    OPTS="${OPTS}vp1BatchNEvents=$FLAG_BATCH_N_EVENTS"
+fi
 if [ "x$FLAG_BATCH_OUT_FOLDER" != "x" ]; then
     if [ "x$OPTS" != "x" ]; then OPTS="$OPTS;"; fi
     OPTS="${OPTS}vp1BatchOutFolder=\"$FLAG_BATCH_OUT_FOLDER\""
 fi
+if [ "x$FLAG_BATCH_RANDOM_CONFIG" != "x0" ]; then
+    if [ "x$OPTS" != "x" ]; then OPTS="$OPTS;"; fi
+    OPTS="${OPTS}vp1BatchRandomConfiguration=True"
+fi
 if [ "x$FLAG_LARHV" != "x0" ]; then
     if [ "x$OPTS" != "x" ]; then OPTS="$OPTS;"; fi
     OPTS="${OPTS}vp1LarHvData=True"
diff --git a/graphics/VP1/VP1Algs/share/vp1.py b/graphics/VP1/VP1Algs/share/vp1.py
index 93b547cbeaccaf8ef91b61774ef101798085a6db..862ce04dc59f9da452ebd603fb2e4a344fe17054 100644
--- a/graphics/VP1/VP1Algs/share/vp1.py
+++ b/graphics/VP1/VP1Algs/share/vp1.py
@@ -22,7 +22,9 @@ if not 'vp1MultiAvailableSrcDirs' in dir(): vp1MultiAvailableSrcDirs = []
 if not 'vp1TrigDecXML' in dir(): vp1TrigDecXML=""
 if not 'vp1Batch' in dir(): vp1Batch=False
 if not 'vp1BatchAllEvents' in dir(): vp1BatchAllEvents=False
+if not 'vp1BatchNEvents' in dir(): vp1BatchNEvents=0
 if not 'vp1BatchOutFolder' in dir(): vp1BatchOutFolder=""
+if not 'vp1BatchRandomConfiguration' in dir(): vp1BatchRandomConfiguration=False
 if not 'vp1LarHvData' in dir(): vp1LarHvData=False
 # if not 'vp1FullToroids' in dir(): vp1FullToroids=False
 if not 'vp1CruiseTime' in dir(): vp1CruiseTime=0
@@ -228,8 +230,12 @@ if vp1Batch:
     os.putenv("VP1_BATCHMODE","1")
 if vp1BatchAllEvents:
     os.putenv("VP1_BATCHMODE_ALLEVENTS","1")
+if vp1BatchNEvents > 0:
+    os.putenv("VP1_BATCHMODE_NEVENTS", str(vp1BatchNEvents) )
 if (vp1BatchOutFolder != ""):
     os.putenv("VP1_BATCHMODE_OUT_FOLDER", vp1BatchOutFolder)
+if vp1BatchRandomConfiguration:
+    os.putenv("VP1_BATCHMODE_RANDOMCONFIG","1")
 
 
 
diff --git a/graphics/VP1/VP1AlgsBatch/CMakeLists.txt b/graphics/VP1/VP1AlgsBatch/CMakeLists.txt
index 9eafa4947feaf0926094a795230f49c2694db687..e7f4918b4485550573a4d84ea4d0202501c9b9b3 100644
--- a/graphics/VP1/VP1AlgsBatch/CMakeLists.txt
+++ b/graphics/VP1/VP1AlgsBatch/CMakeLists.txt
@@ -24,3 +24,5 @@ atlas_add_component( VP1AlgsBatch
 
 # Install files from the package:
 atlas_install_runtime( share/*.vp1 )
+atlas_install_joboptions( share/*.py )
+atlas_install_scripts( share/vp1batch )
diff --git a/graphics/VP1/VP1AlgsBatch/share/vp1batch b/graphics/VP1/VP1AlgsBatch/share/vp1batch
new file mode 100755
index 0000000000000000000000000000000000000000..defba01ff99a5ffc29128a52369a0e56de4e1fbd
--- /dev/null
+++ b/graphics/VP1/VP1AlgsBatch/share/vp1batch
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Script for constructing the command which launches vp1 with advanced "batch" options
+#
+# Author: Riccardo.Maria.Bianchi@cern.ch
+# 11 Jan 2019
+
+
+INPUT_FILE=$1
+
+
+echo "Running on input file '$1'"
+
+JOBOPT="VP1AlgsBatch/vp1batch.py"
+if [ -f vp1batch.py ]; then
+    JOBOPT=vp1batch.py
+fi
+
+
+echo athena.py $ATHENAOPTS  -c "'$OPTS'" $JOBOPT $EXTRAJOBOPT
diff --git a/graphics/VP1/VP1AlgsBatch/share/vp1batch.py b/graphics/VP1/VP1AlgsBatch/share/vp1batch.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f9dcf5433b17fe10c0ae94c2430148306059bc3
--- /dev/null
+++ b/graphics/VP1/VP1AlgsBatch/share/vp1batch.py
@@ -0,0 +1,13 @@
+
+if not 'vp1InputFile' in dir(): vp1InputFiles = []
+
+# customize the algorithm
+from VP1AlgsBatch.VP1AlgsBatchConf import VP1BatchOnLatestEvent
+VP1BatchOnLatestEvent.DestinationDirectory="atlasathome_test" 
+VP1BatchOnLatestEvent.UseRandomVP1ConfigFile=True
+
+
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+topSequence += VP1BatchOnLatestEvent()
+topSequence.TimeOut=0
diff --git a/graphics/VP1/VP1AlgsBatch/src/VP1BatchOnLatestEvent.cxx b/graphics/VP1/VP1AlgsBatch/src/VP1BatchOnLatestEvent.cxx
index 23594404a1ddd7d9b0ddff529432a3b2d63c7e17..541101c33c0dfa487ce226a9a458f6b59fc19476 100755
--- a/graphics/VP1/VP1AlgsBatch/src/VP1BatchOnLatestEvent.cxx
+++ b/graphics/VP1/VP1AlgsBatch/src/VP1BatchOnLatestEvent.cxx
@@ -151,7 +151,7 @@ void VP1BatchOnLatestEvent::makeEventDisplay() {
 	msg(MSG::INFO) << "--> Input VP1 Configuration file: " << m_inputVP1CfgFile
 			<< endmsg;
 
-	// LAUNCH VP1-Batch on the latest-produced ESD file
+	// build the command to launch VP1-Batch on the latest-produced ESD file
 	std::string commandStr = "vp1 -batch";
 
 	// add custom output folder, if user specified it
diff --git a/graphics/VP1/VP1Base/src/IVP13DStandardChannelWidget.cxx b/graphics/VP1/VP1Base/src/IVP13DStandardChannelWidget.cxx
index 51d69c6725b433670a0caf72e907f39c315082f7..327ea8befd68e656332e2f5400ea1125c37663c2 100644
--- a/graphics/VP1/VP1Base/src/IVP13DStandardChannelWidget.cxx
+++ b/graphics/VP1/VP1Base/src/IVP13DStandardChannelWidget.cxx
@@ -435,7 +435,7 @@ void IVP13DStandardChannelWidget::stopSpinning()
 //___________________________________________________________________________
 QPixmap IVP13DStandardChannelWidget::getSnapshot(bool transp, int width, bool batch)
 {
-	VP1Msg::messageDebug("IVP13DStandardChannelWidget::getSnapshot()  - transparent bkg: "+QString(transp)+" , width: "+QString::number(width)+" , batch: "+QString(batch));
+	VP1Msg::messageDebug("IVP13DStandardChannelWidget::getSnapshot()  - transparent bkg: "+QString::number(transp)+" , width: "+QString::number(width)+" , batch: "+QString::number(batch));
   //   SoToVRML2Action tovrml2;
   //   tovrml2.apply(m_d->selection);
   //   SoVRMLGroup *newroot = tovrml2.getVRML2SceneGraph();
diff --git a/graphics/VP1/VP1Gui/CMakeLists.txt b/graphics/VP1/VP1Gui/CMakeLists.txt
index c4a375db06b8ddb3873bc498f268d520fa5b88be..73e9f8a7757977441bab0ae883cfe477adf82d71 100644
--- a/graphics/VP1/VP1Gui/CMakeLists.txt
+++ b/graphics/VP1/VP1Gui/CMakeLists.txt
@@ -35,8 +35,3 @@ atlas_add_library( VP1Gui VP1Gui/*.h src/*.h src/*.cxx src/*.qrc
    Qt5::PrintSupport
    PRIVATE_LINK_LIBRARIES ${COIN3D_LIBRARIES} ${SOQT_LIBRARIES} Qt5::Network )
 
-   
-# Install files from the package:
-##atlas_install_scripts( share/* ) # installs into bin/
-atlas_install_runtime( share/* ) # install into share/
-   
diff --git a/graphics/VP1/VP1Gui/VP1Gui/VP1ExecutionScheduler.h b/graphics/VP1/VP1Gui/VP1Gui/VP1ExecutionScheduler.h
index 773653e88a7038e617fea1ed17a7f1096f9404ad..dac9c6a0f891ee97aae97870d32467e93de6f85e 100644
--- a/graphics/VP1/VP1Gui/VP1Gui/VP1ExecutionScheduler.h
+++ b/graphics/VP1/VP1Gui/VP1Gui/VP1ExecutionScheduler.h
@@ -54,10 +54,13 @@ public:
 
 
   //init/cleanup:
-  static VP1ExecutionScheduler* init(StoreGateSvc* eventStore,StoreGateSvc* detStore,
-				     ISvcLocator* svcLocator,IToolSvc*toolSvc,
+  static VP1ExecutionScheduler* init(StoreGateSvc* eventStore,
+		             StoreGateSvc* detStore,
+				     ISvcLocator* svcLocator,
+					 IToolSvc*toolSvc,
 				     QStringList joboptions,
-				     QString initialCruiseMode = "NONE", unsigned initialCruiseSeconds = 10,
+				     QString initialCruiseMode = "NONE",
+					 unsigned initialCruiseSeconds = 10,
 				     QString singleEventSource = "",
 				     QString singleEventLocalTmpDir = "",
 				     unsigned localFileCacheLimit = 10,
diff --git a/graphics/VP1/VP1Gui/VP1Gui/VP1MainWindow.h b/graphics/VP1/VP1Gui/VP1Gui/VP1MainWindow.h
index 7c6a48ee98f952fd479906a78504086b56c75ea1..7507310dac57ad7e71aba72aa2e10da4594963cb 100644
--- a/graphics/VP1/VP1Gui/VP1Gui/VP1MainWindow.h
+++ b/graphics/VP1/VP1Gui/VP1Gui/VP1MainWindow.h
@@ -120,6 +120,7 @@ public slots:
   void selectedChannelChanged(IVP1ChannelWidget*);
 
   void loadConfigurationFromFile(QString file);
+  void replaceConfigurationFile(QString file);
 
   void addToMessageBox( const QString&, const QString& extrastyleopts = "",
 			const QString& title = "", const QString& titleextrastyleopts = "" );
diff --git a/graphics/VP1/VP1Gui/VP1Gui/VP1TabManager.h b/graphics/VP1/VP1Gui/VP1Gui/VP1TabManager.h
index 645fbca0a6999d3d6031abcf05d55a72fe0a20a7..8f21ea43185c1561a162776f32188d58ff264449 100644
--- a/graphics/VP1/VP1Gui/VP1Gui/VP1TabManager.h
+++ b/graphics/VP1/VP1Gui/VP1Gui/VP1TabManager.h
@@ -69,6 +69,8 @@ public slots:
   void moveChannelToTab(QString channeluniquename,QString tabname);
   void cloneChannelToTab(QString channeluniquename,QString tabname);
   void cloneTab(QString oldtabname,QString newtabname);
+  void removeAllTabs();
+
 
   void saveConfigurationToFile(QString filename,const bool& askonoverride=true);
   void loadConfigurationFromFile(QString filename,const QMap<QString,QString>& availableplugins);
diff --git a/graphics/VP1/VP1Gui/src/VP1ExecutionScheduler.cxx b/graphics/VP1/VP1Gui/src/VP1ExecutionScheduler.cxx
index 4cbc02c35b2ba88d572196aaa9c63dd004e65f9d..bac60a9e21fcbb5e4e9f02a37651d12fae81b131 100644
--- a/graphics/VP1/VP1Gui/src/VP1ExecutionScheduler.cxx
+++ b/graphics/VP1/VP1Gui/src/VP1ExecutionScheduler.cxx
@@ -56,6 +56,8 @@
 #include "VP1Base/VP1AthenaPtrs.h"
 #include "VP1Base/VP1Settings.h"
 
+#include "VP1UtilsBase/VP1BatchUtilities.h"
+
 #include <QApplication>
 #include <QProgressBar>
 #include <QDesktopWidget>
@@ -64,6 +66,7 @@
 #include <QCursor>
 #include <QTimer>
 #include <QSet>
+#include <QStringList>
 #include <QMessageBox>
 
 #include <Inventor/C/errors/debugerror.h>
@@ -75,6 +78,19 @@
 #include <sstream>      // std::ostringstream
 #include <ctime>
 #include <stdexcept>
+#include <string>
+#include <vector>
+
+
+
+std::vector<std::string> qstringlistToVecString(QStringList list)
+{
+	std::vector<std::string> vec;
+	foreach(QString str, list) {
+		vec.push_back(str.toStdString());
+	}
+	return vec;
+}
 
 
 //___________________________________________________________________
@@ -87,8 +103,13 @@ public:
 	VP1Prioritiser * prioritiser;
 	VP1MainWindow* mainwindow;
 
+	long int eventsProcessed;
+
 	bool batchMode;
 	bool batchModeAllEvents;
+	int batchModeNEvents;
+	bool batchModeRandomConfig;
+	VP1BatchUtilities* batchUtilities;
 
 	VP1AvailEvents * availEvents;
 
@@ -178,19 +199,24 @@ private:
 
 //___________________________________________________________________
 VP1ExecutionScheduler::VP1ExecutionScheduler( QObject * parent,
-		StoreGateSvc* eventStore,StoreGateSvc* detStore,
-		ISvcLocator* svcLocator,IToolSvc*toolSvc,
+		StoreGateSvc* eventStore,
+		StoreGateSvc* detStore,
+		ISvcLocator* svcLocator,
+		IToolSvc*toolSvc,
 		VP1AvailEvents * availEvents)
 : QObject(parent), m_d(new Imp)
 {
 	m_d->availEvents = availEvents;
 	VP1AthenaPtrs::setPointers(eventStore,detStore,svcLocator,toolSvc);
+	m_d->eventsProcessed = 0;
 
 	m_d->scheduler = this;
 	m_d->prioritiser = new VP1Prioritiser(this);
 	m_d->mainwindow = new VP1MainWindow(this,availEvents);//mainwindow takes ownership of available events
 	m_d->batchMode = false;
+	m_d->batchUtilities = nullptr;
 	m_d->batchModeAllEvents = false;
+	m_d->batchModeNEvents = 0;
 	m_d->allSystemsRefreshed = false;
 	m_d->goingtonextevent=true;
 	m_d->currentsystemrefreshing=0;
@@ -211,19 +237,24 @@ VP1ExecutionScheduler::VP1ExecutionScheduler( QObject * parent,
 
 	// Init and show the main window of VP1
 	SoQt::init( m_d->mainwindow );// SoQt::init( "VP1" );
+
+	// check if 'batch mode'
 	bool batchMode = VP1QtUtils::environmentVariableIsSet("VP1_BATCHMODE"); // ::getenv("VP1_BATCHMODE");
 	qDebug() << "VP1ExecutionScheduler:: Do we run in 'batch' mode?" << batchMode;
 	if (batchMode) {
 		VP1Msg::messageWarningAllRed("User has run VP1 in 'batch-mode', so the main window of the program will not be shown.");
 		m_d->batchMode = true;
+
+		// check if the user set the "all events" option as well
+		m_d->batchModeAllEvents = VP1QtUtils::environmentVariableIsSet("VP1_BATCHMODE_ALLEVENTS");
+
+		// check if the user set the "random configuration file" option as well
+		m_d->batchModeRandomConfig = VP1QtUtils::environmentVariableIsSet("VP1_BATCHMODE_RANDOMCONFIG");
 	}
 	else {
 		m_d->mainwindow->show();
 	}
 
-    // If in batch mode, let's see if the user set the "all events" options as well
-	m_d->batchModeAllEvents = VP1QtUtils::environmentVariableIsSet("VP1_BATCHMODE_ALLEVENTS"); // ::getenv("VP1_BATCHMODE");
-
 
 	m_d->pb = m_d->mainwindow->progressbar;
 	m_d->pbtimer = new QTimer(this);
@@ -265,6 +296,7 @@ VP1ExecutionScheduler::VP1ExecutionScheduler( QObject * parent,
 VP1ExecutionScheduler::~VP1ExecutionScheduler()
 {
 	m_d->refreshtimer->stop();
+	delete m_d->batchUtilities;
 	delete m_d->mainwindow;
 	delete m_d->prioritiser;
 	delete m_d->globalEventFilter;
@@ -272,8 +304,10 @@ VP1ExecutionScheduler::~VP1ExecutionScheduler()
 }
 
 //___________________________________________________________________
-VP1ExecutionScheduler* VP1ExecutionScheduler::init( StoreGateSvc* eventStore, StoreGateSvc* detStore,
-		ISvcLocator* svcLocator, IToolSvc*toolSvc,
+VP1ExecutionScheduler* VP1ExecutionScheduler::init( StoreGateSvc* eventStore,
+		StoreGateSvc* detStore,
+		ISvcLocator* svcLocator,
+		IToolSvc*toolSvc,
 		QStringList joboptions,
 		QString initialCruiseMode,
 		unsigned initialCruiseSeconds,
@@ -354,7 +388,19 @@ VP1ExecutionScheduler* VP1ExecutionScheduler::init( StoreGateSvc* eventStore, St
 	} else {
 		foreach(QString opt,joboptions)
     		  scheduler->m_d->mainwindow->loadConfigurationFromFile(opt);
+
+		if ( scheduler->m_d->batchMode ) {
+			if (scheduler->m_d->batchModeRandomConfig ) {
+				scheduler->m_d->batchUtilities = new VP1BatchUtilities( qstringlistToVecString(joboptions) );
+			}
+			QString batchNevents = VP1QtUtils::environmentVariableValue("VP1_BATCHMODE_NEVENTS");
+			if (batchNevents > 0 ) {
+				scheduler->m_d->batchModeNEvents = batchNevents.toInt();
+			}
+		}
 	}
+
+
 	if (scheduler->m_d->mainwindow->tabWidget_central->count()<=1) {
 		if (initialCruiseMode=="TAB") {
 			VP1Msg::message("ERROR: Can not start in cruisemode TAB unless there are at least 2 tabs loaded from initial .vp1 files. Reverting to cruise mode NONE.");
@@ -396,6 +442,7 @@ VP1ExecutionScheduler* VP1ExecutionScheduler::init( StoreGateSvc* eventStore, St
 	if ( cruisesecs>0 )
 		scheduler->m_d->mainwindow->spinBox_cruise->setValue(cruisesecs);
 
+
 	return scheduler;
 }
 
@@ -504,8 +551,15 @@ bool VP1ExecutionScheduler::executeNewEvent(const int& runnumber, const unsigned
 
 
 	VP1Msg::messageDebug("batch mode: " + QString::number(m_d->batchMode));
+
+	if (m_d->batchModeRandomConfig) {
+		VP1Msg::messageDebug("User chose 'batch' and 'batch-random-config'. So we now replace the configuration with a random one from the input set...");
+		QString randomConfigFile = QString::fromStdString( m_d->batchUtilities->getRandomConfigFile() );
+		m_d->mainwindow->replaceConfigurationFile(randomConfigFile);
+	}
+
 	if ( m_d->batchMode && m_d->allVisibleRefreshed() ) { // or m_d->allSystemsRefreshed ???
-			VP1Msg::messageDebug("We're in batch mode, skipping...");
+			VP1Msg::messageDebug("We're in batch mode, skipping the execution of the GUI...");
 	} else {
 		VP1Msg::messageDebug("skipEvent: " + QString::number(m_d->skipEvent));
 		if(m_d->skipEvent) {
@@ -544,7 +598,8 @@ bool VP1ExecutionScheduler::executeNewEvent(const int& runnumber, const unsigned
 		eraseSystem(s);
 	}
 
-	VP1Msg::messageDebug("event processed.");
+	++m_d->eventsProcessed; // we don't use Athena's tools for this, so we can use this in VP1Light as well.
+	VP1Msg::messageDebug("event processed. " + QString::number(m_d->eventsProcessed) + " events processed so far.");
 
 	//Let channels know we are going to the next event now:
 	foreach(IVP1ChannelWidget*cw, m_d->mainwindow->tabManager()->allChannels()) {
@@ -553,7 +608,8 @@ bool VP1ExecutionScheduler::executeNewEvent(const int& runnumber, const unsigned
 
 	qApp->processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers);
 
-	VP1Msg::messageDebug("mainwindow->mustQuit: " + QString::number(m_d->mainwindow->mustQuit()) );
+
+	VP1Msg::messageDebug("mainwindow->mustQuit ? " + QString::number(m_d->mainwindow->mustQuit()) );
 	return !m_d->mainwindow->mustQuit();
 }
 
@@ -737,6 +793,7 @@ void VP1ExecutionScheduler::refreshSystem(IVP1System*s)
 		if (m_d->batchMode) {
 
 			VP1Msg::messageDebug("we are in 'batch-mode'...");
+			VP1Msg::messageDebug("batchModeNEvents: " + QString::number(m_d->batchModeNEvents) + " - m_d->eventsProcessed: " + QString::number(m_d->eventsProcessed) );
 
 			// saving the snapshot of the 3D window to a file
 			QString save_ok = saveSnaphsotToFile(s, true);
@@ -748,16 +805,34 @@ void VP1ExecutionScheduler::refreshSystem(IVP1System*s)
 
 
 			if (m_d->batchModeAllEvents) {
+				VP1Msg::messageWarningAllRed("******************************************************************");
 				VP1Msg::messageWarningAllRed("'batch mode' with 'all events' option. Moving to the next event...");
 				VP1Msg::messageWarningAllRed("******************************************************************");
+				// N.B. calling QApplication::quit() here it makes VP1 move to the next event;
 				QApplication::quit();
-			} else {
-				VP1Msg::messageWarningRed("'batch mode'. Now exiting VP1");
-
-				// Here we want to close VP1 completely.
+				// Now, VP1ExecutionScheduler::executeNewEvent() will end, then VP1Gui::executeNewEvent() will end, then they will start again: first VP1Gui then VP1ExecutionScheduler.
+			} else if ( m_d->batchModeNEvents > 0 ) {
+			    if ( m_d->batchModeNEvents == m_d->eventsProcessed+1) { // here we use +1 because this is performed after the creation of the event snapshot. //TODO: maybe we can move this to a more natural place, at the beginning or at the end of an event
+			    	VP1Msg::messageWarningAllRed("******************************************************************");
+			    	VP1Msg::messageWarningAllRed("'batch mode' with 'batch-n-events' option. Processed the " + QString::number(m_d->eventsProcessed+1) + " events set by the user. Now exiting VP1");
+			    	VP1Msg::messageWarningAllRed("******************************************************************");
+			    	m_d->mainwindow->close();
+			    } else {
+			    	VP1Msg::messageWarningAllRed("'batch mode' with 'batch-n-events' option. Moving to the next event...");
+			    	// N.B. calling QApplication::quit() here it makes VP1 move to the next event;
+			    	QApplication::quit();
+			    	// Now, VP1ExecutionScheduler::executeNewEvent() will end, then VP1Gui::executeNewEvent() will end, then they will start again: first VP1Gui then VP1ExecutionScheduler.
+			    }
+			}
+			else {
+				// We come here if the user did not choose to run batch mode on all events.
+				// Thus, we want to close VP1 completely.
 				// So, in order to do that, we have to call "MainWindow::close()"
+				VP1Msg::messageWarningRed("'batch mode'. Done. Now exiting VP1");
 				m_d->mainwindow->close();
 			}
+
+
 		}
 	}
 }
diff --git a/graphics/VP1/VP1Gui/src/VP1Gui.cxx b/graphics/VP1/VP1Gui/src/VP1Gui.cxx
index e57459886c9c1adb526708b03696013858abf5c5..920f95ddbd20e93d6fa4f914cfee09408812f264 100644
--- a/graphics/VP1/VP1Gui/src/VP1Gui.cxx
+++ b/graphics/VP1/VP1Gui/src/VP1Gui.cxx
@@ -184,7 +184,10 @@ void VP1Gui::init()
   VP1Msg::message("               Launching the VP1 GUI");
   VP1Msg::message("===================================================");
   VP1Msg::message("");
-  m_d->the_scheduler = VP1ExecutionScheduler::init(m_d->sg,m_d->detstore,m_d->svclocator,m_d->toolSvc,
+  m_d->the_scheduler = VP1ExecutionScheduler::init(m_d->sg,
+		                 m_d->detstore,
+						 m_d->svclocator,
+						 m_d->toolSvc,
 						 m_d->initialvp1files,
 						 m_d->initialCruiseMode,m_d->initialCruiseSeconds,
 						 m_d->singleEventSource,m_d->singleEventLocalTmpDir,
@@ -204,13 +207,9 @@ void VP1Gui::cleanup()
 //____________________________________________________________________
 bool VP1Gui::executeNewEvent( const int& run, const uint64_t& event, const unsigned& triggerType, const unsigned& time )
 {
-	//tests
-	int evN = event;
-	qulonglong evNqu = event;
+  VP1Msg::messageDebug("Examining new event ( run# "+QString::number(run)+", event# "+QString::number(event)+" )");
 
-	qDebug() << "tests:" << QString::number(event) << QString::number(evN) << QString::number(evNqu);
 
-  VP1Msg::messageDebug("Examining new event ( run# "+QString::number(run)+", event# "+QString::number(event)+" )");
 
   bool b = m_d->the_scheduler->executeNewEvent(run,event,triggerType,time);
 
@@ -219,7 +218,7 @@ bool VP1Gui::executeNewEvent( const int& run, const uint64_t& event, const unsig
   // only when the user clicks on the "Next event" button.
 
   VP1Msg::messageDebug("Leaving event ( run# "+QString::number(run)+", event# "+QString::number(event)+" )"
-		       +(nextRequestedEventFile().empty()?QString(""):". Next requested event: "+QString(nextRequestedEventFile().c_str())));
+		       +(nextRequestedEventFile().empty()?QString(""):". Next requested event file: "+QString(nextRequestedEventFile().c_str())));
 
   VP1Msg::messageDebug("end of VP1Gui::executeNewEvent().");
 
diff --git a/graphics/VP1/VP1Gui/src/VP1MainWindow.cxx b/graphics/VP1/VP1Gui/src/VP1MainWindow.cxx
index 9eae4f616a5f615a442547ea54a3f1824cca2786..341509dbe8471c50a431597402e31baba2e83246 100644
--- a/graphics/VP1/VP1Gui/src/VP1MainWindow.cxx
+++ b/graphics/VP1/VP1Gui/src/VP1MainWindow.cxx
@@ -1318,6 +1318,14 @@ void VP1MainWindow::loadConfigurationFromFile(QString file) {
 	m_tabmanager->loadConfigurationFromFile(file,availablePluginFiles());
 }
 
+//_________________________________________________________________________________
+void VP1MainWindow::replaceConfigurationFile(QString file)
+{
+	VP1Msg::messageDebug("VP1MainWindow::replaceConfigurationFile() : " + file);
+	m_tabmanager->removeAllTabs();
+	m_tabmanager->loadConfigurationFromFile(file,availablePluginFiles());
+}
+
 //_________________________________________________________________________________
 void VP1MainWindow::listenOnTcp()
 {
diff --git a/graphics/VP1/VP1Gui/src/VP1TabManager.cxx b/graphics/VP1/VP1Gui/src/VP1TabManager.cxx
index 3baf2179f05e0dd33bf629943448ecac67f3da4c..c72b69ef6b37057fc498e3fba58458b50b4bc83a 100644
--- a/graphics/VP1/VP1Gui/src/VP1TabManager.cxx
+++ b/graphics/VP1/VP1Gui/src/VP1TabManager.cxx
@@ -543,6 +543,7 @@ QStringList VP1TabManager::tabList() {
 void VP1TabManager::removeTab( QString tabname ) {
 
   if (!m_d->checkTabnameExists(tabname)) return;
+
   bool save = m_d->dontEmitVisibilityChanges;
   m_d->dontEmitVisibilityChanges=true;
 
@@ -578,6 +579,17 @@ void VP1TabManager::removeTab( QString tabname ) {
   currentVisibleChanged();
 }
 
+
+//_______________________________________________________________________
+void VP1TabManager::removeAllTabs()
+{
+	VP1Msg::messageDebug("VP1TabManager::removeAllTabs()");
+	foreach(QString tab, tabList() ) {
+		removeTab(tab);
+	}
+}
+
+
 //___________________________________________________________________________________
 void VP1TabManager::removeChannel(QString channeluniquename) {
 
diff --git a/graphics/VP1/VP1UtilsBase/CMakeLists.txt b/graphics/VP1/VP1UtilsBase/CMakeLists.txt
index 160aa3359f696c6fea764eb90b531f8b8b21545a..371b777769cd435d4b5770b1de70fdd7a1b4ccae 100644
--- a/graphics/VP1/VP1UtilsBase/CMakeLists.txt
+++ b/graphics/VP1/VP1UtilsBase/CMakeLists.txt
@@ -15,3 +15,7 @@ atlas_add_library( VP1UtilsBase
    VP1UtilsBase/*.h src/*.cxx
    PUBLIC_HEADERS VP1UtilsBase
    PRIVATE_LINK_LIBRARIES Qt5::Core )
+
+# Install files from the package:
+atlas_install_runtime( share/*.vp1 ) # default VP1 config files for batch mode
+atlas_install_runtime( share/*.png ) # ATLAS logo
diff --git a/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1BatchUtilities.h b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1BatchUtilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..37725e8595836e3e50cab82801c9bd426eb4e6dc
--- /dev/null
+++ b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1BatchUtilities.h
@@ -0,0 +1,41 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Header file for class VP1BatchUtilities                //
+//                                                         //
+//  Author: Riccardo Maria Bianchi <rbianchi@cern.ch>      //
+//                                                         //
+//  Initial version: Jan 2019                              //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+
+#ifndef VP1UTILSBASE_VP1BatchUtilities
+#define VP1UTILSBASE_VP1BatchUtilities
+
+//NB: There should never be any Qt (or Athena of course) includes in this file!!!
+#include <string>
+#include <vector>
+
+
+class VP1BatchUtilities
+{
+public:
+	VP1BatchUtilities(std::vector<std::string> files);
+	~VP1BatchUtilities() {};
+
+	std::string getRandomConfigFile();
+
+	static void overlayATLASlogo();
+	static void overlayEventDetails(unsigned long runNumber, unsigned long eventNumber, std::string humanTimestamp);
+
+private:
+	std::vector<std::string> m_files;
+	int m_indexFile;
+	int m_lastIndexFile;
+};
+
+#endif
diff --git a/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1FileUtilities.h b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1FileUtilities.h
index 2f76de8d3229de73dedcad1270193a94126ead8b..d13e560466923592da97b6f3937bffd887419ed9 100644
--- a/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1FileUtilities.h
+++ b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1FileUtilities.h
@@ -19,7 +19,6 @@
 #define VP1FILEUTILITIES_H
 
 //NB: There should never be any Qt (or Athena of course) includes in this file!!!
-
 #include <string>
 
 class VP1FileUtilities
@@ -54,10 +53,7 @@ public:
 		      int timeStamp,
               std::string textLabel = "");
 
-  //
-
   // **** Check if file exists ****
-
   static bool fileExistsAndReadable(const std::string&);
 
 private:
diff --git a/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1TimeUtilities.h b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1TimeUtilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..791eaa476821a91d5a4279574bd8c0af7eb44aef
--- /dev/null
+++ b/graphics/VP1/VP1UtilsBase/VP1UtilsBase/VP1TimeUtilities.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Header file for class VP1BatchUtilities                //
+//                                                         //
+//  Author: Riccardo Maria Bianchi <rbianchi@cern.ch>      //
+//                                                         //
+//  Initial version: Jan 2019                              //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+
+#ifndef VP1UTILSBASE_VP1TimeUtilities
+#define VP1UTILSBASE_VP1TimeUtilities
+
+
+//NB: There should never be any Qt (or Athena of course) includes in this file!!!
+#include <ctime> /* time_t, time, ctime */
+#include <string>
+
+
+class VP1TimeUtilities
+{
+public:
+	static std::string getHumanReadableTimestamp(time_t t_timestamp);
+
+private:
+	VP1TimeUtilities();
+	~VP1TimeUtilities();
+};
+
+#endif
diff --git a/graphics/VP1/VP1Gui/share/ATLAS-Logo-New_300pixels.png b/graphics/VP1/VP1UtilsBase/share/ATLAS-Logo-New_300pixels.png
similarity index 100%
rename from graphics/VP1/VP1Gui/share/ATLAS-Logo-New_300pixels.png
rename to graphics/VP1/VP1UtilsBase/share/ATLAS-Logo-New_300pixels.png
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wGeo_frontView.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wGeo_frontView.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..301d9b99702cae33fd65f4305f44757a5999ae2c
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wGeo_frontView.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wIDGeo.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wIDGeo.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..f3fc6cbf3430410282fe718d5fc48c6ec936e56f
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wIDGeo.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_3D.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_3D.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..68e29b6a8bebec446c3eb476d0c1ebbcaf7e7be3
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_3D.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wGeo_3D.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wGeo_3D.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..927fdee1a45cadbd49ab6b19fd82b22d18f9e165
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wGeo_3D.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wOpenCalo_wGeo_3D.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wOpenCalo_wGeo_3D.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..5a970a8f379cf4ceb0d3bbf070bf212d90fdf03a
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wOpenCalo_wGeo_3D.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..d12f0539f9b898238d8de9eb992b30509ec06980
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_IAview.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_IAview.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..a89af52bc0665a8987eb0baa1986b7ef8c89656e
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_IAview.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wBarrel.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wBarrel.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..7bd6280374e2f8a6b708d230639694c0040f6d86
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wBarrel.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wMDT.vp1 b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wMDT.vp1
new file mode 100644
index 0000000000000000000000000000000000000000..dcf4dbd655643a1cbd13c0ab7504ead1b219c455
Binary files /dev/null and b/graphics/VP1/VP1UtilsBase/share/vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wMDT.vp1 differ
diff --git a/graphics/VP1/VP1UtilsBase/src/VP1BatchUtilities.cxx b/graphics/VP1/VP1UtilsBase/src/VP1BatchUtilities.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..84fcf8bfec0c043d568aaab7ee09d329d5c6bdb2
--- /dev/null
+++ b/graphics/VP1/VP1UtilsBase/src/VP1BatchUtilities.cxx
@@ -0,0 +1,153 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Implementation of class VP1BatchUtilities              //
+//                                                         //
+//  Author: Riccardo Maria Bianchi <rbianchi@cern.ch>      //
+//                                                         //
+//  Initial version: Jan 2019                              //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+
+#include "VP1UtilsBase/VP1BatchUtilities.h"
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <random> // C++11
+#include <iomanip>
+#include <functional>
+
+
+
+VP1BatchUtilities::VP1BatchUtilities(std::vector<std::string> files) : m_indexFile(0), m_lastIndexFile(0)
+{
+	m_files = files;
+	std::cout << "Got vector of " << files.size() << " items" << std::endl;
+	// Iterate and print values of vector
+	for(std::string n : m_files) {
+	        std::cout << n << '\n';
+	}
+}
+
+
+std::string VP1BatchUtilities::getRandomConfigFile()
+{
+	std::cout <<"VP1BatchUtilities::getRandomConfigFile()" << std::endl;
+
+	std::string configFile;
+
+
+	int nConfigFiles = m_files.size();
+	std::cout << " ===> # config files: " << nConfigFiles << std::endl;
+
+	// setup random generator in [0, nConfigFiles]
+    int nPositions = nConfigFiles - 1;
+	auto seed = std::random_device{}();
+	auto randomDist = std::bind(std::uniform_int_distribution<int>(0, nPositions ),
+			std::mt19937(seed));
+
+	// get a random index,
+	m_indexFile = randomDist();
+	// avoiding having the same index in a row
+	while ( m_indexFile == m_lastIndexFile ) {
+		m_indexFile = randomDist();
+	}
+	m_lastIndexFile = m_indexFile;
+	std::cout << " ===> random index: " << m_indexFile << std::endl;
+
+	configFile = m_files[m_indexFile];
+	std::cout << " ===> random file: " << configFile << std::endl;
+
+	return configFile;
+
+}
+
+// Overlay the ATLAS logo to the image
+void VP1BatchUtilities::overlayATLASlogo()
+{
+    /*
+     * different example commands for logo overlay:
+     *
+	 * std::string commandStr =  "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry 150x150+0+0 -depth 8 test.png"; // this set the logo size to 150px and it draws it at (0,0)px
+	 * std::string commandStr =  "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry +10+10 -depth 8 test.png"; // this uses the original logo size and it draws it at (10,10)px
+     */
+
+	std::string commandStr = "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry +10+10 -depth 8 `cat latest_vp1image`";
+
+	std::cout << " ===> overlay the ATLAS logo: " << commandStr << std::endl;
+	try {
+		system(commandStr.c_str());
+	} catch (std::runtime_error& err) {
+		std::cout << "Exception caught: " << err.what() << std::endl;
+		std::cout << "Unable to run 'convert'!" << std::endl;
+	}
+}
+
+// Overlay the event details to the image
+// it replaces the original image with a version having event details on it
+void VP1BatchUtilities::overlayEventDetails(unsigned long runNumber, unsigned long eventNumber, std::string humanTimestamp)
+{
+
+	std::string nRun = std::to_string(runNumber);
+	std::string nEvent = std::to_string(eventNumber);
+
+	/* 
+     * example of different bash command for event details overlay:
+     *
+	 * nRun=0; nEvent=4;                   img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80  -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n2015-02-02, 15:10:00' ${img} +swap -gravity SouthEast -composite ${img}-30
+	 * nRun=0; nEvent=4; timestamp='ciao'; img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80  -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n'${timestamp}         ${img} +swap -gravity SouthEast -composite ${img}-31
+	 * nRun=0; nEvent=4; timestamp='2015-02-02T10:10:00'; img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80  -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n'${timestamp} ${img} +swap -gravity SouthEast -composite ${img}-36
+    */
+
+	std::string commandStr;
+
+	// setting bash variables
+	commandStr += "nRun="+nRun+"; ";
+	commandStr += "nEvent="+nEvent+"; ";
+	if (humanTimestamp != "0") commandStr += "timestamp='"+humanTimestamp+"'; "; // 'timestamp' must not have white spaces
+
+	// get input image
+	commandStr += "img=`cat latest_vp1image`; ";           // get the filename of the latest image produced
+	commandStr += "width=$(identify -format %W ${img}); "; // get the width of the image
+	commandStr += "width=$(( ${width} * 3 / 10 )); ";      // set the caption width as a fraction of the image width
+
+	// ImageMagik 'convert' command settings. (ImageMagik is installed by default on SLC LXPLUS machines)
+	commandStr = commandStr
+			+ "convert "
+			+  "-background '#0008' "  // semi-transparent grey bkg
+			+  "-geometry +20+20 "     // set an offset to the label position
+			+  "-gravity West "        // set text position inside the caption space (justification)
+			+  "-fill white "          // text font color
+			+  "-size ${width}x80 "    // set text size relative to 'width'
+
+			+  "-font Courier "        // text font
+			+  "-density 72 "          // dots-per-inch resolution
+			+  "-pointsize 18 "        // text size in points
+			//+  "-interline-spacing 4 " // additional number of pixels between lines of text (only with ImageMagik >= 6.5.5-8!!! Lxplus has 6.7 but not all SLC6 machines...)
+
+			//+  "caption:'Run number: ${nRun}' " // set the caption text
+			//+  (m_timeStamp > 0 ? "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} " : "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} ") // set the caption text; '\n' needs to be double-escaped while passed to system()
+			+  "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} " // set the caption text; '\n' needs to be double-escaped while passed to system()
+
+			+  "${img} "             // imput image
+			+  "+swap "
+			+  "-gravity SouthEast "   // set overall caption position
+			+  "-composite "
+			+  "${img}";              // output image: here we replace the original image
+
+
+	std::cout << " ===> overlay the event details: " << commandStr << std::endl;
+	try {
+		system(commandStr.c_str());
+	} catch (std::runtime_error& err) {
+		std::cout << "Exception caught: " << err.what() << std::endl;
+		std::cout << "Unable to run 'convert'!" << std::endl;
+	}
+}
+
+
diff --git a/graphics/VP1/VP1UtilsBase/src/VP1TimeUtilities.cxx b/graphics/VP1/VP1UtilsBase/src/VP1TimeUtilities.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..14b7697aa7e7775e18f0c5c4cec6e858b7189a17
--- /dev/null
+++ b/graphics/VP1/VP1UtilsBase/src/VP1TimeUtilities.cxx
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////
+//                                                         //
+//  Implementation of class VP1TimeUtilities              //
+//                                                         //
+//  Author: Riccardo Maria Bianchi <rbianchi@cern.ch>      //
+//                                                         //
+//  Initial version: Jan 2019                              //
+//                                                         //
+/////////////////////////////////////////////////////////////
+
+
+#include "VP1UtilsBase/VP1TimeUtilities.h"
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <iostream>
+
+
+std::string VP1TimeUtilities::getHumanReadableTimestamp(time_t t_timestamp)
+{
+	tm *ltm = localtime(&t_timestamp);
+
+	std::string humanTimestamp;
+
+	std::ostringstream ostri;
+	ostri  << 1900 + ltm->tm_year
+			<< "-" << 1 + ltm->tm_mon  // tm_mon is in the range [0, 11], so 1 must be added to get real months
+			<< "-" << ltm->tm_mday
+			<< "T" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec; // << "CEST"; FIXME: check if time zone is available on data file
+
+	humanTimestamp = ostri.str();
+	//std::cout << "'human readable' timestamp: " << m_humanTimestamp << std::endl;
+	return humanTimestamp;
+}
+