Skip to content

Commit b99120d

Browse files
sawenzelclaude
andcommitted
Compare the hit counts with a sequential run in the MT equality test
This makes the test fail for a detector clone that makes no hits. - A sequential run with the same seed is the reference for the number of hits of each detector. - The hits must not be zero and must agree within a tolerance, 0.2 by default. - --seeding subevent checks the default per-sub-event seeding as well. https://its.cern.ch/jira/browse/O2-7305 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f9359f6 commit b99120d

1 file changed

Lines changed: 53 additions & 17 deletions

File tree

‎run/o2-sim-mt-equality.sh‎

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
#!/usr/bin/env bash
22
# Checks that multithreaded Geant4 in o2-sim gives the same output for 1 and N transport threads.
33
#
4-
# Usage: o2-sim-mt-equality.sh [-n events] [-j threads] [-g generator] [--field kG] [--seed seed] [--workdir dir] [module ...]
4+
# Usage: o2-sim-mt-equality.sh [-n events] [-j threads] [-g generator] [--field kG] [--seed seed]
5+
# [--seeding track|subevent] [--tolerance fraction] [--workdir dir] [module ...]
56
#
67
# Runs the same seeded workload with --isMT -j 1 and --isMT -j N and compares the kinematics and hit files
7-
# event by event and branch by branch. Exits with 1 at the first difference. Without modules, the passive
8-
# geometry with ITS is used.
8+
# event by event and branch by branch. A sequential run with the same seed is the reference for the number of
9+
# hits of each detector, which must not be zero and must agree within the tolerance (default 0.2). Exits with
10+
# 1 at the first difference. Without modules, the passive geometry with ITS is used.
911

1012
nev=2
1113
nthreads=2
1214
gen=pythia8pp
1315
field=-5
1416
seed=4711
17+
seeding=track
18+
tolerance=0.2
1519
workdir=
1620
modules=()
1721
while [ $# -gt 0 ]; do
@@ -21,18 +25,25 @@ while [ $# -gt 0 ]; do
2125
-g) gen=$2; shift 2 ;;
2226
--field) field=$2; shift 2 ;;
2327
--seed) seed=$2; shift 2 ;;
28+
--seeding) seeding=$2; shift 2 ;;
29+
--tolerance) tolerance=$2; shift 2 ;;
2430
--workdir) workdir=$2; shift 2 ;;
25-
-h|--help) sed -n '2,9p' $0; exit 0 ;;
31+
-h|--help) sed -n '2,10p' $0; exit 0 ;;
2632
*) modules+=("$1"); shift ;;
2733
esac
2834
done
2935
[ ${#modules[@]} -eq 0 ] && modules=(HALL MAG DIPO COMP PIPE ABSO SHIL ITS)
36+
case $seeding in
37+
track) seedconf="SimCutParams.trackSeed=true" ;;
38+
subevent) seedconf="SimCutParams.trackSeed=false" ;;
39+
*) echo "unknown seeding '$seeding', use track or subevent"; exit 1 ;;
40+
esac
3041
o2sim=o2-sim
3142
[ -x "$O2_ROOT/bin/o2-sim" ] && o2sim=$O2_ROOT/bin/o2-sim
3243
[ -z "$workdir" ] && workdir=$(mktemp -d ${TMPDIR:-/tmp}/o2sim-mt-equality-XXXXXX)
3344
mkdir -p $workdir && cd $workdir || exit 1
3445

35-
# content hash per event and branch of the o2sim tree, independent of the basket layout
46+
# content hash and number of entries per event and branch of the o2sim tree, independent of the basket layout
3647
cat > hashtree.C <<'EOF'
3748
void hashtree(const char* fname)
3849
{
@@ -63,43 +74,68 @@ void hashtree(const char* fname)
6374
md5.Update((UChar_t*)buf.Buffer(), buf.Length());
6475
md5.Final();
6576
printf("HASH event %lld branch %s %s\n", i, name.c_str(), md5.AsString());
77+
if (auto proxy = cl->GetCollectionProxy()) {
78+
TVirtualCollectionProxy::TPushPop helper(proxy, obj);
79+
printf("COUNT event %lld branch %s %u\n", i, name.c_str(), proxy->Size());
80+
}
6681
}
6782
}
6883
}
6984
EOF
7085

71-
run() { # <threads>
72-
local dir=mt$1
86+
run() { # <directory> <o2-sim mode options>
87+
local dir=$1
88+
shift
7389
mkdir -p $dir && cd $dir
74-
$o2sim --isMT 1 -j $1 -n $nev -g $gen -e TGeant4 --seed $seed --field $field -m ${modules[@]} \
75-
--configKeyValues "SimCutParams.trackSeed=true" > sim.log 2>&1
90+
$o2sim "$@" -n $nev -g $gen -e TGeant4 --seed $seed --field $field -m ${modules[@]} --configKeyValues "$seedconf" > sim.log 2>&1
7691
local rc=$?
7792
if [ $rc -ne 0 ] || ! grep -q "SIMULATION RETURNED SUCCESFULLY" sim.log; then
78-
echo "o2-sim with $1 threads failed (exit code $rc), see $workdir/$dir"
93+
echo "o2-sim in $dir failed (exit code $rc), see $workdir/$dir"
7994
exit 1
8095
fi
8196
for f in o2sim_Kine.root o2sim_Hits*.root; do
82-
[ -f $f ] && root -l -b -q "../hashtree.C(\"$f\")" 2>/dev/null | grep "^HASH" | sed "s/^HASH/$f/" > $f.hashes
97+
[ -f $f ] || continue
98+
root -l -b -q "../hashtree.C(\"$f\")" 2>/dev/null > $f.out
99+
grep "^HASH" $f.out | sed "s/^HASH/$f/" > $f.hashes
100+
grep "^COUNT" $f.out | awk '{n += $NF} END {print n + 0}' > $f.count
83101
done
84102
cd ..
85103
}
86104

87-
echo "o2-sim MT equality: ${modules[*]}, $nev events of $gen, field $field kG, 1 against $nthreads threads, in $workdir"
88-
run 1
89-
run $nthreads
105+
echo "o2-sim MT equality: ${modules[*]}, $nev events of $gen, field $field kG, $seeding seeding, 1 against $nthreads threads, in $workdir"
106+
run seq -j 1
107+
run mt1 --isMT 1 -j 1
108+
run mt$nthreads --isMT 1 -j $nthreads
90109
status=0
91110
for h in mt1/*.hashes; do
92111
f=$(basename $h)
112+
file=${f%.hashes}
93113
if [ ! -s $h ]; then
94-
echo "${f%.hashes}: no entries"
114+
echo "$file: no entries"
95115
status=1
96116
elif cmp -s $h mt$nthreads/$f; then
97-
echo "${f%.hashes}: identical ($(wc -l < $h) event-branch hashes)"
117+
echo "$file: identical ($(wc -l < $h) event-branch hashes)"
98118
else
99-
echo "${f%.hashes}: DIFFERS, first at $(diff $h mt$nthreads/$f | grep -m1 '^<' | cut -d' ' -f3-6)"
119+
echo "$file: DIFFERS, first at $(diff $h mt$nthreads/$f | grep -m1 '^<' | cut -d' ' -f3-6)"
100120
status=1
101121
fi
102122
done
103123
[ $(ls mt$nthreads/*.hashes | wc -l) -eq $(ls mt1/*.hashes | wc -l) ] || { echo "the runs wrote different output files"; status=1; }
124+
# the sequential run as reference for the number of hits, which catches a detector clone that makes no hits
125+
for c in seq/o2sim_Hits*.root.count; do
126+
[ -f "$c" ] || continue
127+
file=$(basename ${c%.count})
128+
nseq=$(cat $c)
129+
nmt=$(cat mt1/$file.count 2>/dev/null || echo 0)
130+
if [ "$nmt" -eq 0 ]; then
131+
echo "$file: no hits in MT (sequential: $nseq)"
132+
status=1
133+
elif ! awk -v a=$nseq -v b=$nmt -v t=$tolerance 'BEGIN {exit !(a > 0 && (a - b < 0 ? b - a : a - b) <= t * a)}'; then
134+
echo "$file: $nmt hits in MT against $nseq in sequential mode, beyond the tolerance $tolerance"
135+
status=1
136+
else
137+
echo "$file: $nmt hits in MT, $nseq in sequential mode"
138+
fi
139+
done
104140
[ $status -eq 0 ] && echo "EQUALITY TEST PASSED" || echo "EQUALITY TEST FAILED"
105141
exit $status

0 commit comments

Comments
 (0)