From ff148744b0ef8be989701366682810a4c40a8d1b Mon Sep 17 00:00:00 2001
From: Sylvester Joosten <sjoosten@anl.gov>
Date: Wed, 18 Nov 2020 16:36:41 +0000
Subject: [PATCH] Polished environment script, and made utility scripts
 executable from any directory

---
 .gitignore              |  9 +---
 config/env.sh           | 91 ++++++++++++++++++++++++++-----------
 util/build_detector.sh  | 67 +++++++++++++++++++++-------
 util/download.sh        | 21 +++++----
 util/start_dev_shell.sh | 99 ++++++++++++++++++++++++++++++++++-------
 5 files changed, 213 insertions(+), 74 deletions(-)

diff --git a/.gitignore b/.gitignore
index 529ec47a..5a88418e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,10 +44,5 @@ calorimeters/test/
 # output files
 results/*
 
-#intermediary files for testign
-detector/*
-detector-build/*
-topside
-accelerator
-
-*.sif
+# local runtime files
+.local
diff --git a/config/env.sh b/config/env.sh
index 786fcf5c..73aaf598 100755
--- a/config/env.sh
+++ b/config/env.sh
@@ -1,41 +1,80 @@
 #!/bin/bash
 
-if [[ ! -n  "${JUGGLER_DETECTOR}" ]] ; then 
+## =============================================================================
+## Global configuration variables for the benchmark scripts
+## The script defines the following environment variables that are meant to
+## be overriden by the Gitlab continuous integration (CI)
+##
+##  - JUGGLER_DETECTOR:       detector package to be used for the benchmark
+##  - JUGGLER_N_EVENTS:       #events processed by simulation/reconstruction
+##  - JUGGLER_INSTALL_PREFIX: location where Juggler (digi/recon) is installed
+##
+## It also defines the following additional variables for internal usage
+##  - LOCAL_PREFIX:           prefix for packages installed during the benchmark
+##  - DETECTOR_PREFIX:        prefix for the detector definitions
+##  - DETECTOR_PATH:          actual path with the detector definitions
+##
+## Finally, it makes sure LOCAL_PREFIX and JUGGLER_PREFIX are added to PATH
+## and LD_LIBRARY_PATH
+## =============================================================================
+
+echo "Setting up the Physics Benchmarks environment"
+
+## =============================================================================
+## Default variable definitions, normally these should be set
+## by the CI. In case of local development you may want to change these
+## in case you would like to modify the detector package or
+## number of events to be analyzed during the benchmark
+
+## Detector package to be used during the benchmark process
+if [ ! -n  "${JUGGLER_DETECTOR}" ] ; then 
   export JUGGLER_DETECTOR="topside"
 fi
+echo "JUGGLER_DETECTOR:       ${JUGGLER_DETECTOR}"
 
-if [[ ! -n  "${JUGGLER_N_EVENTS}" ]] ; then 
+## Number of events that will be processed by the reconstruction
+if [ ! -n  "${JUGGLER_N_EVENTS}" ] ; then 
   export JUGGLER_N_EVENTS=100
 fi
+echo "JUGGLER_N_EVENTS:       ${JUGGLER_N_EVENTS}"
 
-if [[ ! -n  "${JUGGLER_INSTALL_PREFIX}" ]] ; then 
+## Install prefix for juggler, needed to locate the Juggler xenv files.
+## Also used by the CI as install prefix for other packages where needed.
+## You should not have to touch this. Note that for local usage a different 
+## prefix structure is automatically used.
+if [ ! -n  "${JUGGLER_INSTALL_PREFIX}" ] ; then 
   export JUGGLER_INSTALL_PREFIX="/usr/local"
 fi
+## Ensure the juggler prefix is an absolute path
+export JUGGLER_INSTALL_PREFIX=`realpath ${JUGGLER_INSTALL_PREFIX}`
+echo "JUGGLER_INSTALL_PREFIX: ${JUGGLER_INSTALL_PREFIX}"
 
-# not sure this is needed
-if [[ ! -n "${DETECTOR_INSTALL_PREFIX}" ]]; then
-  # reuse the custom juggler install prefix for detector if in CI
-  if [ ! -n ${CI} ]; then
-    echo "Setting up detector prefix for CI usage"
-    export DETECTOR_INSTALL_PREFIX=${JUGGLER_INSTALL_PREFIX}
-  # for local builds, just use a "detector" directory
-  else 
-    echo "Setting up detector prefix for local usage"
-    export DETECTOR_INSTALL_PREFIX="detector"
-  fi
-fi
+## =============================================================================
+## Other utility variables that govern how some of the dependent packages
+## are built and installed. You should not have to change these.
 
-## ensure absolute paths
-# not sure this is needed either 
-export JUGGLER_INSTALL_PREFIX=`realpath ${JUGGLER_INSTALL_PREFIX}`
-export DETECTOR_INSTALL_PREFIX=`realpath ${DETECTOR_INSTALL_PREFIX}`
+## local prefix to be used for local storage of packages
+## downloaded/installed during the benchmark process
+LOCAL_PREFIX=".local"
+mkdir -p ${LOCAL_PREFIX}
+export LOCAL_PREFIX=`realpath ${LOCAL_PREFIX}`
+echo "LOCAL_PREFIX:           ${LOCAL_PREFIX}"
+
+## detector prefix: prefix for the detector definitions
+export DETECTOR_PREFIX="${LOCAL_PREFIX}/detector"
+mkdir -p ${DETECTOR_PREFIX}
+echo "DETECTOR_PREFIX:        ${DETECTOR_PREFIX}"
 
-## Ensure Juggler and Detector prefixes are in our paths
-export PATH=${JUGGLER_INSTALL_PREFIX}/bin:${DETECTOR_INSTALL_PREFIX}/bin:${PATH}
-export LD_LIBRARY_PATH=${JUGGLER_INSTALL_PREFIX}/lib:${DETECTOR_INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}
+## detector path: actual detector definition path
+export DETECTOR_PATH="${DETECTOR_PREFIX}/${JUGGLER_DETECTOR}"
+echo "DETECTOR_PATH:          ${DETECTOR_PATH}"
 
+## =============================================================================
+## Setup PATH and LD_LIBRARY_PATH to include our prefixes
+echo "Adding JUGGLER_INSTALL_PREFIX and LOCAL_PREFIX to PATH and LD_LIBRARY_PATH"
+export PATH=${JUGGLER_INSTALL_PREFIX}/bin:${LOCAL_PREFIX}/bin:${PATH}
+export LD_LIBRARY_PATH=${JUGGLER_INSTALL_PREFIX}/lib:${LOCAL_PREFIX}/lib:${LD_LIBRARY_PATH}
 
-## setup root results artifact path
-# this should be in the CI File instead
-# https://docs.gitlab.com/ee/ci/yaml/README.html#variables
-# export RESULTS_PATH=`realpath results`
+## =============================================================================
+## That's all!
+echo "Environment setup complete."
diff --git a/util/build_detector.sh b/util/build_detector.sh
index 3d08a73c..41716d5c 100755
--- a/util/build_detector.sh
+++ b/util/build_detector.sh
@@ -1,28 +1,65 @@
 #!/bin/bash
 
-## Init the environment
+## make sure we launch this script from the project root directory
+PROJECT_ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"/..
+pushd ${PROJECT_ROOT}
+
+## =============================================================================
+## Build and install the JUGGLER_DETECTOR detector package into our local prefix
+## This script will only work when executed from the project root directory. 
+## =============================================================================
+
+## =============================================================================
+## Load the environment variables. To build the detector we need the following
+## variables:
+##
+## - JUGGLER_DETECTOR: the detector package we want to use for this benchmark
+## - LOCAL_PREFIX:     location where local packages should be installed
+## - DETECTOR_PREFIX:  prefix for the detector definitions 
+## - DETECTOR_PATH:    full path for the detector definitions
+##                     this is the same as ${DETECTOR_PREFIX}/${JUGGLER_DETECTOR}
+##
+## You can ready config/env.sh for more in-depth explanations of the variables
+## and how they can be controlled.
 source config/env.sh
 
-## Build and install the detector plugins.
-if [[ ! -d ${JUGGLER_DETECTOR} ]]; then
+## =============================================================================
+## Step 1: download/update the detector definitions (if needed)
+pushd ${DETECTOR_PREFIX}
+
+## We need an up-to-date copy of the detector
+if [ ! -d ${JUGGLER_DETECTOR} ]; then
+  echo "Fetching ${JUGGLER_DETECTOR}"
   git clone https://eicweb.phy.anl.gov/EIC/detectors/${JUGGLER_DETECTOR}.git
-  # this might be temporary. There are multiple solutions here but this is the simple pattern for now
-  # I do not want to use git submodules here -whit
-  git clone https://eicweb.phy.anl.gov/EIC/detectors/accelerator.git
-  pushd ${JUGGLER_DETECTOR}
-  ln -s ../accelerator/eic
-  popd
 else
+  echo "Updating ${JUGGLER_DETECTOR}"
   pushd ${JUGGLER_DETECTOR}
   git pull --ff-only
   popd
+fi
+## We also need an up-to-date copy of the accelerator. For now this is done
+## manually. Down the road we could maybe automize this with cmake
+if [ ! -d accelerator ]; then
+  echo "Fetching accelerator"
+  git clone https://eicweb.phy.anl.gov/EIC/detectors/accelerator.git
+else
+  echo "Updating accelerator"
   pushd accelerator
   git pull --ff-only
   popd
 fi
-mkdir -p detector-build
-pushd detector-build
-# Always keep the detector directory at the top level.
-echo cmake ../${JUGGLER_DETECTOR} -DCMAKE_INSTALL_PREFIX=${DETECTOR_INSTALL_PREFIX} && make -j30 install
-cmake ../${JUGGLER_DETECTOR} -DCMAKE_INSTALL_PREFIX=${DETECTOR_INSTALL_PREFIX} && make -j30 install
-popd
+## Now symlink the accelerator definition into the detector definition
+echo "Linking accelerator definition into detector definition"
+ln -s -f ${DETECTOR_PREFIX}/accelerator/eic ${DETECTOR_PATH}/eic
+
+## =============================================================================
+## Step 2: Compile and install the detector definition
+echo "Building and installing the ${JUGGLER_DETECTOR} package"
+
+mkdir -p ${DETECTOR_PREFIX}/build
+pushd ${DETECTOR_PREFIX}/build
+cmake ${DETECTOR_PATH} -DCMAKE_INSTALL_PREFIX=${LOCAL_PREFIX} && make -j30 install
+
+## =============================================================================
+## Step 3: That's all!
+echo "Detector build/install complete!"
diff --git a/util/download.sh b/util/download.sh
index 5d2d1950..f4664e90 100755
--- a/util/download.sh
+++ b/util/download.sh
@@ -1,12 +1,13 @@
 #!/bin/bash
 
-## Init the environment
-source config/env.sh
+## =============================================================================
+## Download generator & reconstruction artifacts for one or more physics
+## processes.
+## =============================================================================
 
-## Generates different configurations from the master configuration
-## for both electron and muon decay channels
-
-echo "Download generator or reconstruction artifacts for one or more of the physics processes"
+## make sure we launch this script from the project root directory
+PROJECT_ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"/..
+pushd ${PROJECT_ROOT}
 
 PROCS=()
 BRANCH="master"
@@ -25,7 +26,6 @@ function print_the_help {
   exit
 }
 
-
 while [ $# -gt 0 ]
 do
   key="$1"
@@ -51,6 +51,8 @@ do
   esac
 done
 
+echo "Downloading generator & reconstruction artifacts for one or more physics processes"
+
 if [ ${#PROCS[@]} -eq 0 ]; then
   echo "ERROR: need one or more processes: -p <process name> "
   exit 1
@@ -62,9 +64,10 @@ for proc in ${PROCS[@]}; do
   ## FIXME this needs to be smarter, probably through more flags...
   wget https://eicweb.phy.anl.gov/EIC/benchmarks/physics_benchmarks/-/jobs/artifacts/$BRANCH/download?job=${proc}:jpsi_central:process -O results_rec.zip
   echo "Unpacking artifacts..."
-  unzip -u results_gen.zip
-  unzip -u results_rec.zip
+  unzip -u -o results_gen.zip
+  unzip -u -o results_rec.zip
   echo "Cleaning up..."
   rm results_???.zip
 done
+popd
 echo "All done"
diff --git a/util/start_dev_shell.sh b/util/start_dev_shell.sh
index 9741c2a9..a895514a 100755
--- a/util/start_dev_shell.sh
+++ b/util/start_dev_shell.sh
@@ -1,21 +1,86 @@
 #!/bin/bash
 
+## =============================================================================
+## Setup (if needed) and start a development shell environment on Linux or MacOS
+## This script will only work when executed from the project root directory. 
+## =============================================================================
+
+## make sure we launch this script from the project root directory
+PROJECT_ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"/..
+pushd ${PROJECT_ROOT}
+
+## We do not load the global development environment here, as this script is 
+## to be executed on a "naked" system outside of any container 
+
+## =============================================================================
+## Step 1: Parse command line options
+
+## do we want to force-update the container (only affects Linux)
+## default: we do not want to do this.
+FORCE_UPDATE=
+
+function print_the_help {
+  echo "USAGE:    ./util/start_dev_shell [-f]"
+  echo "OPTIONS:"
+  echo "          -f,--force    Force-update container (Only affects Linux)"
+  echo "          -h,--help     Print this message"
+  echo ""
+  echo "  This script will setup and launch a containerized development
+  environment"
+  exit
+}
+while [ $# -gt 0 ]
+do
+  key="$1"
+  case $key in
+    -f|--force)
+      FORCE_UPDATE="true"
+      shift # past value
+      ;;
+    -h|--help)
+      print_the_help
+      shift
+      ;;
+    *)    # unknown option
+      echo "unknown option $1"
+      exit 1
+      ;;
+  esac
+done
+
+## get OS type
 OS=`uname -s`
 
-if [ "${OS}" = "Linux" ]; then
-  echo "Detected OS: Linux"
-  if [ ! -f juggler_latest.sif ]; then
-    echo "Need to fetch singularity image"
-    wget https://eicweb.phy.anl.gov/eic/juggler/-/jobs/artifacts/master/raw/build/juggler.sif?job=docker:singularity -O juggler_latest.sif
-  fi
-  echo "Launching dev shell (through singularity)..."
-  singularity exec juggler_latest.sif eic-shell
-elif [ "${OS}" = "Darwin" ]; then
-  echo "Detector OS: MacOS"
-  echo "Syncing docker container"
-  docker pull sly2j/juggler:latest
-  echo "Launching dev shell (through docker)..."
-  docker run -v /Users:/Users -w=$PWD -i -t --rm sly2j/juggler:latest eic-shell
-else
-  echo "ERROR: dev shell not available for this OS (${OS})"
-fi
+## =============================================================================
+## Step 2: Update container and launch shell
+echo "Launching a containerized development shell"
+
+case ${OS} in
+  Linux)
+    echo "  - Detected OS: Linux"
+    ## Use the same prefix as we use for other local packages
+    export PREFIX=.local/lib
+    if [ ! -f $PREFIX/juggler_latest.sif ] || [ ! -z ${FORCE_UPDATE} ]; then
+      echo "  - Fetching singularity image"
+      mkdir -p $PREFIX
+      wget https://eicweb.phy.anl.gov/eic/juggler/-/jobs/artifacts/master/raw/build/juggler.sif?job=docker:singularity
+      -O $PREFIX/juggler_latest.sif
+    fi
+    echo "  - Using singularity to launch shell..."
+    singularity exec $PREFIX/juggler_latest.sif eic-shell
+    ;;
+  Darwin)
+    echo "  - Detector OS: MacOS"
+    echo "  - Syncing docker container"
+    docker pull sly2j/juggler:latest
+    echo "  - Using docker to launch shell..."
+    docker run -v /Users:/Users -w=$PWD -i -t --rm sly2j/juggler:latest eic-shell
+    ;;
+  *)
+    echo "ERROR: dev shell not available for this OS (${OS})"
+    exit 1
+esac
+
+## =============================================================================
+## Step 3: All done
+echo "Exiting development environment..."
-- 
GitLab