Skip to content

Commit 784a424

Browse files
MapCreation: avoid copying same file twice to the output folder
- use 2 replicas instead of 1 - use proper O2 daily tag - store output alien path of stage 2
1 parent 3e9018a commit 784a424

5 files changed

Lines changed: 43 additions & 7 deletions

File tree

DATA/production/configurations/mapCreationGrid/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,12 @@ Then:
353353

354354
This downloads the *existing* manifest stage 1 already uploaded (does not rebuild it — see the comment in
355355
the script for why that matters), re-stages the three macros if `MACRO_SOURCE=alien`, and submits one
356-
production, same slot granularity as stage 1.
356+
production, same slot granularity as stage 1. It also captures and uploads its own workdir pointer,
357+
`stage2Workdir.<JOBNAME>.txt`, to `MACRO_ALIEN_DIR` — the same mechanism stage 1 uses for its own output
358+
(see Step 3), so an external consumer that needs to locate a specific slot's final `FT_*.root`/smoothed
359+
map (e.g. a downstream pipeline using this stage's output as an input) can reconstruct the path the same
360+
way stage 2 itself reconstructs stage 1's — read `stage2Workdir.<JOBNAME>.txt` for the base, recompute
361+
`COUNTERWIDTH` from this submission's manifest line count, join with the zero-padded subjob index.
357362

358363
**Local single-slot test:**
359364

DATA/production/configurations/mapCreationGrid/mapCreationJob.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ MACRO_ALIEN_DIR_BARE=${MACRO_ALIEN_DIR_BARE:-}
5555
# expect to change it in the wrapper when the data changes -- not here. Empty ("") is a supported value
5656
# meaning "skip bad-ranges filtering entirely for this submission" -- see BAD_RANGES_ARG below.
5757
BAD_RANGES_NAME=${BAD_RANGES_NAME:-Merge_BadIntervals_LHC26_PbPb_DCA-0P300.txt}
58-
#JDL_OUTPUT=*.log@disk=1,*.txt@disk=1,*.info@disk=1
58+
#JDL_OUTPUT=*.log@disk=2,*.txt@disk=2,*.info@disk=2
5959
#JDL_REQUIRE={member(other.GridPartitions,"multicore_8") && (other.CE != "ALICE::NIHAM::PBS64") && (other.CE != "ALICE::KISTI_GSDC::LCG") && (other.CE != "ALICE::SaoPaulo::LCG")};
6060
# Site blacklist: these three CEs excluded from this pipeline's jobs. Setting #JDL_REQUIRE overrides
6161
# grid_submit.sh's own default Requirements entirely (it's read verbatim, not merged -- see

DATA/production/configurations/mapCreationGrid/postProcessJob.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ STAGE1_OUTPUTDIR_BASE=
4444
COUNTERWIDTH=3
4545
MACRO_SOURCE=official
4646
MACRO_ALIEN_DIR_BARE=${MACRO_ALIEN_DIR_BARE:-}
47-
#JDL_OUTPUT=*.log@disk=1,*.txt@disk=1,*.png@disk=1
47+
#JDL_OUTPUT=*.log@disk=2,*.txt@disk=2,*.png@disk=2
4848
#JDL_REQUIRE={member(other.GridPartitions,"multicore_8") && (other.CE != "ALICE::NIHAM::PBS64") && (other.CE != "ALICE::KISTI_GSDC::LCG") && (other.CE != "ALICE::SaoPaulo::LCG")};
4949
# Site blacklist -- same three CEs excluded as stage 1, see that script's comment for why the
5050
# GridPartitions clause has to be repeated here (grid_submit.sh replaces its whole default Requirements,
@@ -215,6 +215,11 @@ echo "${STAGE1_OUTPUT_LOCATION}/${STAGE1_OUTPUT_FILE}" > "${STAGE1_SOURCE_FILE}"
215215
if ! alien.py cp -f "file:${STAGE1_SOURCE_FILE}" "${ALIEN_OUTPUT_DIR}/${STAGE1_SOURCE_FILE}"; then
216216
echo "WARNING: failed to stage ${STAGE1_SOURCE_FILE} -- provenance pointer only, not fatal" >&2
217217
fi
218+
# Remove the local copy now that it's staged: it matches the #JDL_OUTPUT *.txt glob above, and the
219+
# JobAgent's own passive upload of that glob (run after this script exits) does a plain, non-forced
220+
# cp -- it would otherwise collide with the LFN this explicit -f upload just created and put the
221+
# whole subjob into ERROR_SV, even though the actual deliverable upload above succeeded.
222+
rm -f "${STAGE1_SOURCE_FILE}"
218223

219224
# --- QA plots (voxResQA.C) -- runs on just this one slot's smoothed map, same per-slot granularity as
220225
# everything else in this pipeline. Non-fatal on failure: QA is a diagnostic nice-to-have, not a blocking

DATA/production/configurations/mapCreationGrid/submitMapCreation.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ TOPWORKDIR="MapCreation" # replaces grid_submit.sh's generic default "selfjobs
6565
# like the real input data's own convention (.../2026/LHC26ak/572244/...) --
6666
# that needs a real post-processing/organize step, deliberately deferred to a
6767
# later iteration of this pipeline.
68-
PACKAGESPEC="O2::daily-20260729-0000-1"
68+
PACKAGESPEC="O2::daily-20260730-0000-1"
6969
ASUSER="pwg_pp" # your own account = personal quota. "pwg_pp" = charged to that working group's quota AND
7070
# moves MY_JOBWORKDIR/OutputDir to pwg_pp's own space automatically -- see the
7171
# long comment above for why this one value now does everything. NOTE support

DATA/production/configurations/mapCreationGrid/submitPostProcess.sh

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
# script doesn't need its own OutputDir logic, it just needs to read/write consistently with whatever
3333
# stage 1 did.
3434
#
35+
# This wrapper also captures and uploads ITS OWN workdir pointer (stage2Workdir.<JOBNAME>.txt), the same
36+
# way stage 1 does for its own output -- nothing inside this pipeline needed that before (stage 2 is the
37+
# end of the line here), but an external consumer that needs to locate a specific slot's final
38+
# FT_*.root/smoothed map (e.g. a downstream pipeline using it as an input) has no other way to find it,
39+
# since it also lands in an ephemeral ${ALIEN_JDL_OUTPUTDIR}, not a fixed path. Purely additive: this
40+
# stage's own control flow and outputs are unchanged, it just also records where they went.
41+
#
3542
# Usage:
3643
# ./submitPostProcess.sh
3744

@@ -49,7 +56,7 @@ STAGE1_JOBNAME_TAG="mapcreation-v1" # must equal the JOBNAME stage 1 (sub
4956
# actually submitted with -- that's what determined where
5057
# stage 1 staged its map.
5158
TOPWORKDIR="MapCreation"
52-
PACKAGESPEC="O2::daily-20260729-0000-1"
59+
PACKAGESPEC="O2::daily-20260730-0000-1"
5360
ASUSER="pwg_pp" # see the long comment above -- your own account for personal quota, "pwg_pp" for group
5461
# quota (this stage's own submission; independent of what stage 1 used).
5562
MACRO_SOURCE="official" # same meaning/default as stage 1 (submitMapCreation.sh) -- applies
@@ -104,7 +111,8 @@ COUNTERWIDTH=${#N}
104111

105112
TMP_SCRIPT="$(mktemp)"
106113
TMP_WORKDIR_POINTER="$(mktemp)"
107-
trap 'rm -f "${TMP_MANIFEST}" "${TMP_SCRIPT:-}" "${TMP_WORKDIR_POINTER}"' EXIT
114+
TMP_STAGE2_WORKDIR_POINTER="$(mktemp)"
115+
trap 'rm -f "${TMP_MANIFEST}" "${TMP_SCRIPT:-}" "${TMP_WORKDIR_POINTER}" "${TMP_STAGE2_WORKDIR_POINTER}"' EXIT
108116

109117
# ONE submission, mirroring stage 1: the windows live in the manifest, so a subjob index identifies a
110118
# (run, window) pair by itself and there is nothing to loop over.
@@ -142,4 +150,22 @@ GRID_SUBMIT_ARGS=(
142150
)
143151

144152
echo "== Submitting ${JOBNAME} (prodsplit=${N}, asuser=${ASUSER}) =="
145-
"${O2DPG_ROOT}/GRID/utils/grid_submit.sh" "${GRID_SUBMIT_ARGS[@]}"
153+
# Capture grid_submit.sh's own stderr (its "pok" status messages go there) while still showing it live,
154+
# so we can pull out the one line that tells us where this submission's data will actually land -- same
155+
# mechanism submitMapCreation.sh uses for its own stage1Workdir pointer. Nothing downstream needed
156+
# stage 2's own output location before now; this exists so a future consumer (e.g. a pipeline that reads
157+
# stage 2's FT_*.root as an input) can find it without guessing.
158+
SUBMIT_LOG=$("${O2DPG_ROOT}/GRID/utils/grid_submit.sh" "${GRID_SUBMIT_ARGS[@]}" 2>&1 | tee /dev/stderr)
159+
160+
# Strip ANSI color codes (pok() wraps its output in \033[32m...\033[m) before parsing.
161+
MY_JOBWORKDIR=$(echo "${SUBMIT_LOG}" | sed -E 's/\x1b\[[0-9;]*m//g' | sed -n "s/^Your job's working directory will be //p" | tail -1)
162+
if [[ -z "${MY_JOBWORKDIR}" ]]; then
163+
echo "ERROR: could not find \"Your job's working directory will be ...\" in grid_submit.sh's output -- a future consumer of this stage's output won't be able to find it. Aborting." >&2
164+
exit 1
165+
fi
166+
echo "== MY_JOBWORKDIR (stage 2's own) = ${MY_JOBWORKDIR} =="
167+
168+
STAGE2_WORKDIR_POINTER_NAME="stage2Workdir.${JOBNAME}.txt"
169+
echo "${MY_JOBWORKDIR}" > "${TMP_STAGE2_WORKDIR_POINTER}"
170+
alien.py cp -f "file:${TMP_STAGE2_WORKDIR_POINTER}" "${MACRO_ALIEN_DIR}/${STAGE2_WORKDIR_POINTER_NAME}"
171+
echo "== Uploaded ${STAGE2_WORKDIR_POINTER_NAME} =="

0 commit comments

Comments
 (0)