From 98aa3bd3b67948eedcefcba0e2ce1ec30975aa47 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 16 Sep 2026 16:20:57 +0200 Subject: [PATCH 1/2] Run the alternative-reco step of anchorMC in a subshell This fixes a problem in the 2-tag setup of anchorMC.sh and anchorMC_DataEmbedding.sh. - The MC software environment was stashed with 'module save' and brought back with 'module restore'. - 'module restore' fails for a module whose version contains '@', as gpu-system did since alidist of 2026-09-05. - ONNXRuntime depends on gpu-system, so O2, O2Physics, QualityControl and O2PDPSuite were not restored. - o2dpg_sim_workflow_anchored.py then failed with "o2 has no attribute ccdb" and no AO2D was produced. - The alternative-reco step now runs in a subshell, so the MC environment is never modified and nothing needs restoring. Co-Authored-By: Claude Opus 5 --- MC/run/ANCHOR/anchorMC.sh | 117 ++++++++++-------------- MC/run/ANCHOR/anchorMC_DataEmbedding.sh | 110 +++++++++------------- 2 files changed, 92 insertions(+), 135 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index 0aa4832f4..c4ea783de 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -180,8 +180,8 @@ fi export > env_base.env -# The 2-tag / alternative-reco setup below uses 'module save/purge/restore' to stash -# and swap the software environment. If the shell provides no 'module' function, build +# The 2-tag / alternative-reco setup below uses 'module purge' to swap the software +# environment inside a subshell. If the shell provides no 'module' function, build # one on a 'modulecmd' binary. Its location varies by version, so resolve it flexibly # (was hardwired to /usr/bin/modulecmd) and verify it supports saved collections. Fail # hard -- but only when an alternative-reco tag is set, since single-tag jobs never call @@ -237,61 +237,61 @@ if [ ! "${MODULEPATH}" ]; then fi #<----- START OF part that should run under a clean alternative software environment if this was given ------ -if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then - if [ "${LOADEDMODULES}" ]; then - printenv > env_before_stashing.printenv - echo "Stashing initial modules" - module save initial_modules.list # we stash the current modules environment - module list --no-pager - module purge --no-pager - printenv > env_after_stashing.printenv - echo "Modules after purge" - module list --no-pager +# It runs in a subshell, so the MC software environment of this shell stays untouched +# and does not need to be restored afterwards. +( + if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + if [ "${LOADEDMODULES}" ]; then + echo "Unloading initial modules" + module purge --no-pager + fi + echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + source async_environment.env + export > env_async.env fi - echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" - /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env - source async_environment.env - export > env_async.env -fi -# default async_pass.sh script -DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh -# default destenv_extra.sh script -DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh + # default async_pass.sh script + DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh + # default destenv_extra.sh script + DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh -# a specific async_pass.sh script is in the current directory, assume that one should be used -if [[ -f async_pass.sh ]]; then - # the default is executable, however, this may not be, so make it so - chmod +x async_pass.sh - DPGRECO=./async_pass.sh -else - cp -v $DPGRECO . -fi + # a specific async_pass.sh script is in the current directory, assume that one should be used + if [[ -f async_pass.sh ]]; then + # the default is executable, however, this may not be, so make it so + chmod +x async_pass.sh + DPGRECO=./async_pass.sh + else + cp -v $DPGRECO . + fi -# if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one -if [[ ! -f setenv_extra.sh ]] ; then - cp ${DPGSETENV} . - echo_info "Use default setenv_extra.sh from ${DPGSETENV}." -else - echo_info "setenv_extra.sh was found in the current working directory, use it." -fi + # if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one + if [[ ! -f setenv_extra.sh ]] ; then + cp ${DPGSETENV} . + echo_info "Use default setenv_extra.sh from ${DPGSETENV}." + else + echo_info "setenv_extra.sh was found in the current working directory, use it." + fi -chmod u+x setenv_extra.sh + chmod u+x setenv_extra.sh -echo_info "Setting up DPGRECO to ${DPGRECO}" + echo_info "Setting up DPGRECO to ${DPGRECO}" -# take out line running the workflow (if we don't have data input) -[ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh + # take out line running the workflow (if we don't have data input) + [ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh -# create workflow ---> creates the file that can be parsed -export IGNORE_EXISTING_SHMFILES=1 -touch list.list + # create workflow ---> creates the file that can be parsed + export IGNORE_EXISTING_SHMFILES=1 + touch list.list -# run the async_pass.sh and store output to log file for later inspection and extraction of information -./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log -RECO_RC=$? + # run the async_pass.sh and store output to log file for later inspection and extraction of information + ./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log + RECO_RC=$? -echo_info "async_pass.sh finished with ${RECO_RC}" + echo_info "async_pass.sh finished with ${RECO_RC}" + exit ${RECO_RC} +) +RECO_RC=$? if [[ "${RECO_RC}" != "0" ]] ; then exit ${RECO_RC} @@ -305,29 +305,6 @@ fi export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" - -# get rid of the temporary software environment -if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then - module purge --no-pager - # restore the initial software environment - echo "Restoring initial environment" - module --no-pager restore initial_modules.list - module saverm initial_modules.list - - # Restore overwritten O2DPG variables set by modules but changed by user - # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) - # We must avoid piping into a while loop (otherwise the internal export is executed in sub-shell) - printenv > env_after_restore.printenv - while read -r var; do - b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) - a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) - [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" - done < <( - comm -12 \ - <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ - <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort)) - -fi #<----- END OF part that should run under a clean alternative software environment if this was given ------ # now create the local MC config file --> config-json.json diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh index 80cb1daae..b92cf82af 100755 --- a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -196,61 +196,61 @@ if [ ! "${MODULEPATH}" ]; then fi #<----- START OF part that should run under a clean alternative software environment if this was given ------ -if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then - if [ "${LOADEDMODULES}" ]; then - printenv > env_before_stashing.printenv - echo "Stashing initial modules" - module save initial_modules.list # we stash the current modules environment - module list --no-pager - module purge --no-pager - printenv > env_after_stashing.printenv - echo "Modules after purge" - module list --no-pager +# It runs in a subshell, so the MC software environment of this shell stays untouched +# and does not need to be restored afterwards. +( + if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + if [ "${LOADEDMODULES}" ]; then + echo "Unloading initial modules" + module purge --no-pager + fi + echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + source async_environment.env + export > env_async.env fi - echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" - /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env - source async_environment.env - export > env_async.env -fi -# default async_pass.sh script -DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh -# default destenv_extra.sh script -DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh + # default async_pass.sh script + DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh + # default destenv_extra.sh script + DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh -# a specific async_pass.sh script is in the current directory, assume that one should be used -if [[ -f async_pass.sh ]]; then - # the default is executable, however, this may not be, so make it so - chmod +x async_pass.sh - DPGRECO=./async_pass.sh -else - cp -v $DPGRECO . -fi + # a specific async_pass.sh script is in the current directory, assume that one should be used + if [[ -f async_pass.sh ]]; then + # the default is executable, however, this may not be, so make it so + chmod +x async_pass.sh + DPGRECO=./async_pass.sh + else + cp -v $DPGRECO . + fi -# if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one -if [[ ! -f setenv_extra.sh ]] ; then - cp ${DPGSETENV} . - echo_info "Use default setenv_extra.sh from ${DPGSETENV}." -else - echo_info "setenv_extra.sh was found in the current working directory, use it." -fi + # if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one + if [[ ! -f setenv_extra.sh ]] ; then + cp ${DPGSETENV} . + echo_info "Use default setenv_extra.sh from ${DPGSETENV}." + else + echo_info "setenv_extra.sh was found in the current working directory, use it." + fi -chmod u+x setenv_extra.sh + chmod u+x setenv_extra.sh -echo_info "Setting up DPGRECO to ${DPGRECO}" + echo_info "Setting up DPGRECO to ${DPGRECO}" -# take out line running the workflow (if we don't have data input) -[ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh + # take out line running the workflow (if we don't have data input) + [ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh -# create workflow ---> creates the file that can be parsed -export IGNORE_EXISTING_SHMFILES=1 -touch list.list + # create workflow ---> creates the file that can be parsed + export IGNORE_EXISTING_SHMFILES=1 + touch list.list -# run the async_pass.sh and store output to log file for later inspection and extraction of information -./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log -RECO_RC=$? + # run the async_pass.sh and store output to log file for later inspection and extraction of information + ./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log + RECO_RC=$? -echo_info "async_pass.sh finished with ${RECO_RC}" + echo_info "async_pass.sh finished with ${RECO_RC}" + exit ${RECO_RC} +) +RECO_RC=$? if [[ "${RECO_RC}" != "0" ]] ; then exit ${RECO_RC} @@ -264,26 +264,6 @@ fi export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" - -# get rid of the temporary software environment -if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then - module purge --no-pager - # restore the initial software environment - echo "Restoring initial environment" - module --no-pager restore initial_modules.list - module saverm initial_modules.list - - # Restore overwritten O2DPG variables set by modules but changed by user - # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) - printenv > env_after_restore.printenv - comm -12 <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ - <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort) | - while read -r var; do - b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) - a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) - [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" - done -fi #<----- END OF part that should run under a clean alternative software environment if this was given ------ # now create the local MC config file --> config-json.json From b9994ed04721f8b4dae9caa7840cf16f68b252e3 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Wed, 16 Sep 2026 17:38:12 +0200 Subject: [PATCH 2/2] Harden module setup and async environment handling in anchorMC This addresses review comments on the 2-tag subshell change. - The modulecmd probe now checks 'bash list' instead of 'savelist', since save/restore is no longer used. - anchorMC_DataEmbedding.sh now uses the same modulecmd resolution as anchorMC.sh. - A failing 'alienv printenv' of the async tag now stops with a clear error. - The embedding script passes env_async.env with the path of the top directory, not the per-timeframe one. - '2&>' is replaced by '&>' when calling async_pass.sh. Co-Authored-By: Claude Opus 5 --- MC/run/ANCHOR/anchorMC.sh | 16 ++++--- MC/run/ANCHOR/anchorMC_DataEmbedding.sh | 56 +++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index c4ea783de..3d634269e 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -183,7 +183,7 @@ export > env_base.env # The 2-tag / alternative-reco setup below uses 'module purge' to swap the software # environment inside a subshell. If the shell provides no 'module' function, build # one on a 'modulecmd' binary. Its location varies by version, so resolve it flexibly -# (was hardwired to /usr/bin/modulecmd) and verify it supports saved collections. Fail +# (was hardwired to /usr/bin/modulecmd) and verify that it runs. Fail # hard -- but only when an alternative-reco tag is set, since single-tag jobs never call # 'module' -- instead of silently no-op'ing every 'module' call (cf. O2-7070). # The candidate list also resolves symlinks ('readlink -f') and probes the canonical @@ -198,7 +198,7 @@ if ! declare -F module > /dev/null; then "${MODULESHOME:+${MODULESHOME}/libexec/modulecmd}" \ "$(readlink -f /usr/bin/modulecmd 2>/dev/null)" \ /usr/share/Modules/libexec/modulecmd* /usr/share/Modules/*/libexec/modulecmd*; do - if [ -n "${_cand}" ] && [ -x "${_cand}" ] && "${_cand}" bash savelist > /dev/null 2>&1; then + if [ -n "${_cand}" ] && [ -x "${_cand}" ] && "${_cand}" bash list > /dev/null 2>&1; then MODULECMD_BIN="${_cand}" break fi @@ -207,7 +207,7 @@ if ! declare -F module > /dev/null; then echo_info "Using modulecmd at ${MODULECMD_BIN}" elif [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then echo_error "Alternative-reco (2-tag) requested (ALIEN_JDL_O2DPG_ASYNC_RECO_TAG=${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG})" - echo_error "but no 'modulecmd' supporting saved collections (save/restore) was found." + echo_error "but no working 'modulecmd' (needed for 'module purge') was found." echo_error " Looked at: \$MODULECMD='${MODULECMD}', /usr/bin/modulecmd (+readlink -f), PATH," echo_error " \$MODULESHOME/libexec/modulecmd, /usr/share/Modules/{,*/}libexec/modulecmd*." echo_error " Diagnostics: MODULESHOME='${MODULESHOME}' /usr/bin/modulecmd -> '$(readlink -f /usr/bin/modulecmd 2>/dev/null)' PATH='${PATH}'" @@ -246,7 +246,13 @@ fi module purge --no-pager fi echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" - /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" > async_environment.env 2> async_environment.err + # alienv printenv returns 0 also for an unknown tag, so check its output instead + if [ ! -s async_environment.env ] || grep -q "ERROR" async_environment.err; then + echo_error "Could not set up the software environment for ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}:" + cat async_environment.err + exit 1 + fi source async_environment.env export > env_async.env fi @@ -285,7 +291,7 @@ fi touch list.list # run the async_pass.sh and store output to log file for later inspection and extraction of information - ./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log + ./async_pass.sh ${CTF_TEST_FILE:-""} &> async_pass_log.log RECO_RC=$? echo_info "async_pass.sh finished with ${RECO_RC}" diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh index b92cf82af..0f49dda6c 100755 --- a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -178,9 +178,48 @@ fi export > env_base.env +# The 2-tag / alternative-reco setup below uses 'module purge' to swap the software +# environment inside a subshell. If the shell provides no 'module' function, build +# one on a 'modulecmd' binary. Its location varies by version, so resolve it flexibly +# (was hardwired to /usr/bin/modulecmd) and verify that it runs. Fail +# hard -- but only when an alternative-reco tag is set, since single-tag jobs never call +# 'module' -- instead of silently no-op'ing every 'module' call (cf. O2-7070). +# The candidate list also resolves symlinks ('readlink -f') and probes the canonical +# environment-modules install (/usr/share/Modules): on some HPC/container setups +# /usr/bin/modulecmd is a *dangling* symlink (-> /etc/alternatives -> the real .tcl), +# which exec's as "No such file or directory"; this recovers when the real binary is +# still reachable, and otherwise still fails hard (a genuinely missing Modules tree in +# the job's mount namespace is a site-side problem). if ! declare -F module > /dev/null; then + MODULECMD_BIN="" + for _cand in "${MODULECMD}" "/usr/bin/modulecmd" "$(command -v modulecmd 2>/dev/null)" \ + "${MODULESHOME:+${MODULESHOME}/libexec/modulecmd}" \ + "$(readlink -f /usr/bin/modulecmd 2>/dev/null)" \ + /usr/share/Modules/libexec/modulecmd* /usr/share/Modules/*/libexec/modulecmd*; do + if [ -n "${_cand}" ] && [ -x "${_cand}" ] && "${_cand}" bash list > /dev/null 2>&1; then + MODULECMD_BIN="${_cand}" + break + fi + done + if [ -n "${MODULECMD_BIN}" ]; then + echo_info "Using modulecmd at ${MODULECMD_BIN}" + elif [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + echo_error "Alternative-reco (2-tag) requested (ALIEN_JDL_O2DPG_ASYNC_RECO_TAG=${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG})" + echo_error "but no working 'modulecmd' (needed for 'module purge') was found." + echo_error " Looked at: \$MODULECMD='${MODULECMD}', /usr/bin/modulecmd (+readlink -f), PATH," + echo_error " \$MODULESHOME/libexec/modulecmd, /usr/share/Modules/{,*/}libexec/modulecmd*." + echo_error " Diagnostics: MODULESHOME='${MODULESHOME}' /usr/bin/modulecmd -> '$(readlink -f /usr/bin/modulecmd 2>/dev/null)' PATH='${PATH}'" + exit 1 + else + echo_info "No 'modulecmd' found, but no alternative-reco tag is set, so 'module' is not needed; continuing." + fi + export MODULECMD_BIN module() { - eval "$(/usr/bin/modulecmd bash "$@")"; + if [ -z "${MODULECMD_BIN}" ]; then + echo_error "'module ${*}' invoked but no usable 'modulecmd' was found (see earlier diagnostics)." + return 127 + fi + eval "$("${MODULECMD_BIN}" bash "$@")"; } export -f module fi @@ -205,7 +244,13 @@ fi module purge --no-pager fi echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" - /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" > async_environment.env 2> async_environment.err + # alienv printenv returns 0 also for an unknown tag, so check its output instead + if [ ! -s async_environment.env ] || grep -q "ERROR" async_environment.err; then + echo_error "Could not set up the software environment for ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}:" + cat async_environment.err + exit 1 + fi source async_environment.env export > env_async.env fi @@ -244,7 +289,7 @@ fi touch list.list # run the async_pass.sh and store output to log file for later inspection and extraction of information - ./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log + ./async_pass.sh ${CTF_TEST_FILE:-""} &> async_pass_log.log RECO_RC=$? echo_info "async_pass.sh finished with ${RECO_RC}" @@ -266,6 +311,9 @@ export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" #<----- END OF part that should run under a clean alternative software environment if this was given ------ +# the async software environment, referenced from within the per-timeframe workspaces below +ASYNC_ENV_FILE=${PWD}/env_async.env + # now create the local MC config file --> config-json.json # we create the new config output with blacklist functionality ASYNC_CONFIG_BLACKLIST=${ASYNC_CONFIG_BLACKLIST:-${O2DPG_ROOT}/MC/run/ANCHOR/anchor-dpl-options-blacklist.json} @@ -346,7 +394,7 @@ for external_context in collission_context_*.root; do # apply software tagging choice # remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}}" ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE=${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE:-RECO} - remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${PWD}/env_async.env@${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE}}" + remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ASYNC_ENV_FILE}@${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE}}" # potentially add CCDB timemachine timestamp remainingargs="${remainingargs} ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}}" # add external collision context injection