Skip to content

MatchCosmics: cosmics in collision data + raw-cluster writer with TOF - #15915

Open
matthias-kleiner wants to merge 13 commits into
AliceO2Group:devfrom
matthias-kleiner:cosmics-matcher-writer-clean
Open

matthias-kleiner wants to merge 13 commits into
AliceO2Group:devfrom
matthias-kleiner:cosmics-matcher-writer-clean

Conversation

@matthias-kleiner

Copy link
Copy Markdown
Contributor

Collect cosmic muons in the PbPb async reconstruction for TPC calibration (distortion correction with tracks that do not come from the vertex). This PR makes the matcher usable in collision data and adds an optional writer of the raw data needed for an offline refit. Details and validation are in the commit messages.

  1. MatchCosmics: include the last compatible vertex in the DCA veto (off-by-one fix, affects --use-pv-info).
  2. MatchCosmics: selection of cosmics in collision data, named presets (--cosmics-preset physics-v1; all new cuts off by default).
  3. MatchCosmics: energy-loss sign along the muon's flight; optional eLossSign in GPUO2InterfaceRefit / GPUTrackingRefit (default 0: unchanged for other users).
  4. Cosmics: raw clusters of matched cosmics with TOF tag (--enable-cluster-output → o2_cosmics_full.root): TPC road clusters, ITS / TOF / TRD hits, TOF time, refit at the TOF time.
  5. MatchCosmics: same-side TPC-only legs compared at a common time (option, off; not in the preset, it adds fakes in PbPb).
  6. MatchCosmics: TOF flight pair of the legs as selection criterion (on in physics-v1).

Default behaviour changes: muon mass for seeds and refit, energy-loss sign along the flight (cosmics run 562658: 357 → 358 cosmics, q/pt within ±1 %); the veto fix with --use-pv-info. Everything else is opt-in.

Usage (PbPb async; O2DPG wiring is a follow-up):
o2-cosmics-match-workflow --track-sources TPC --cosmics-preset physics-v1 --enable-cluster-output

Validation: PbPb 568041 from CTF with physics-v1 (19684 TFs): 0.29 cosmics per TF, 15 % TOF-tagged; matcher 0.50 + collector 0.16 CPU s per TF; 1.1 kB per TF. Cosmic MC with PbPb-like distortions: 79.5 % of the muons matched, 0 wrong pairs.

Open points: purity of the untagged cosmics is not yet measured on data (the TOF-tagged sample is the clean one); the collector repeats parts of the matcher's TOF and refit code (a shared helper is possible).

final5_best50 final5_first50

Left: 50 TOF-tagged cosmics from PbPb 568041 with physics-v1 (TOF-tagged, refitted at the TOF time, > 150 TPC clusters, p > 2 GeV). Right: the first 50 cosmics without quality cuts, as written to o2_cosmics_full.root. TPC clusters of both legs, ITS clusters, TOF hits; one colour per cosmic.

matthias-kleiner and others added 4 commits October 8, 2026 08:57
vtIDMax is the id of the last compatible vertex (inclusive), but the veto
loop stopped before it: a seed associated to a single vertex (vtIDMin ==
vtIDMax) was never checked, so with --use-pv-info the DCA cut never
removed collision tracks associated to one vertex.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In collision data nearly all seeds are collision tracks and TPC-only legs had their z ignored, so any two tracks back-to-back in
the transverse plane were paired (PbPb: minutes per TF, tens of thousands of fake pairs). New settings, all off by default and
switched on together by the preset physics-v1 (o2-cosmics-match-workflow --cosmics-preset physics-v1; --configKeyValues can still
override single keys, unknown names are fatal):

- Seed cuts: minSeedNClTPC, minSeedDCAxy and minSeedDCAxyNSigma reject short TPC fragments and seeds passing the beam line
  (cosmics through the beam line are indistinguishable from collision tracks anyway).
- z test of TPC-only legs (constrainTPCOnlyZ): a one-side TPC-only track has z relative to its time0, z(t) = z + side*vD*(t-time0);
  a CE-crossing or non-TPC-only track has an absolute z. The legs are compared at a common time (same side, or one leg with known
  time); for legs on opposite sides z continuity fixes the common time, which must lie in both time brackets. That time, with its
  error sigma_z / (2 vD) (~0.3 mus), is used for the refit and as the time of the cosmic (before: the centre of the bracket overlap,
  tens of mus, which put the legs at the wrong z: cosmics run 562658 A x C chi2Match median 3.5e4 -> 43). For all other pairs the
  time error of the cosmic stays the half-width of the bracket overlap.
- Same-half veto (vetoSameHalf): pairs whose two legs lie on the same side of the closest approach in the transverse plane (two
  pieces of one leg) are rejected; skipped when a leg's reference point is within 20 cm of the closest approach.
- maxChi2Match: cut on the chi2 of the refitted top/bottom legs.
- minPtOppositeSides: for TPC-only legs on opposite sides z continuity defines the time, so z does not reject random pairs (94 % of
  the PbPb candidates). Both legs (in checkPair, before the winner selection) and the refitted cosmic need pT above it (scaled with
  the field).

Unconditionally, the seeds and the refit use the muon mass (and charge 1) for the material corrections instead of the TPC track's
PID from dE/dx (a leg tagged as kaon or proton got that mass): cosmic MC 6987 -> 7003 correct pairs (0 wrong), cosmics run 562658
357 -> 358; the refitted q/pt changes by +-0.4 % (MC) and +-1 % (562658) (q16-q84, pT < 20 GeV).

physics-v1: pT > 1 GeV, |DCA_xy| > 3 cm and > 10 sigma, >= 30 TPC clusters; systematic errors for the leg comparison y 0.5 cm,
snp 0.02, q/pt 0.05 (true pairs had pulls 2-4x too wide) with crude chi2 < 50; open per-parameter windows except tgl (3 sigma);
chi2Match < 1000; z test and same-half veto on; minPtOppositeSides 2 GeV.
Validation, TPC-only legs: cosmic MC with PbPb-like distortions 7003 of 8638 cosmics correct (81.1 %, 0 wrong pairs); cosmics run
562658 358 cosmics; PbPb 2025 LHC25an 567939 (19 kHz) 0.37 cosmics per TF (3.90 without the pT cut), 568041 reconstructed from
CTF 0.30 per TF (3203 in 10546 TFs; the PbPb numbers before the muon mass, which leaves 4 PbPb TFs unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gy-loss sign in the TPC refit

The propagator applies the energy-loss correction along the direction of the track parameters (loss forward, gain backward), and
refitWinners fits a cosmic from the bottom leg to the top one: after the inward refit of the bottom leg its parameters are inverted
and carried up through the top leg, i.e. they describe a particle moving upward. A cosmic muon flies downward, from the top leg to
the bottom leg, so only the inward refit of the bottom leg (backward along its parameters = backward along the flight) had the
physical sign; the propagation of the inverted bottom leg to the top leg, the outward refit of the top leg, the inward refit of the
top leg, its propagation to the bottom parameter and the propagation of the top seeds to the DCA had the opposite one. The sign is
now imposed along the flight in all of them, with the propagator's signCorr argument.

GPUO2InterfaceRefit / GPUTrackingRefit::RefitTrackAsTrackParCov (TrackParCov + cluster references) get the analogous optional last
argument eLossSign, passed to their propagations (0 = along the parameters as before, +1 gain, -1 loss; flipped on the optional
way to the reference X when that runs against the refit direction); the default keeps the behaviour for all other users.

MC truth (cosmic MC, 1073 muons crossing the inner region; true parameters at the bottom TPC inner radius propagated back through
the closest approach to the top one, compared to the true momentum there, q16 / q50 / q84 in MeV): true loss between the two
14.5 / 16.1 / 19.9 MeV (median for |z| at the closest approach 0-25 / 25-50 / 50-75 cm); predicted - true with the sign of the
upward fit -14.5 / -15.2 / -18.6 MeV (as without material: the gain inward and the loss outward cancel), with the sign along the
flight +1.2 / +2.1 / +1.0 MeV (spread q16-q84 about -2 ... +9 MeV). The matched cosmics hardly change because the two halves'
errors cancel in their average: cosmic MC 7003 -> 7006 correct pairs (0 wrong), chi2Match median unchanged; cosmics run 562658
358 cosmics before and after; refitted q/pt within +-0.05 %. The halves themselves (e.g. the momentum at the TPC entrance) change
by the full loss.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h TOF (--enable-cluster-output)

The async reconstruction stores neither TPC tracks nor TPC clusters, so the leg references of TrackCosmics cannot be resolved
offline. New device cosmics-cluster-collector (+ cosmics-full-writer -> o2_cosmics_full.root, tree cosmicsFull, one entry per TF):
- per cosmic (o2::dataformats::CosmicTrack, DataFormatsGlobalTracking): the TrackCosmics, the TPC tracks of both legs, the raw
  ClusterNative + sector/row of each leg's attached clusters and of all clusters in a road around the leg (flags: attached / road /
  used by any TPC track / found with the absolute time on the other TPC side), the ITS compact clusters (chip, anchor pixel, pattern
  ID, ROF BC; pattern bytes for patterns not in the dictionary), TOF clusters (raw time, ToT, channel), TRD tracklet words (+ trigger
  BC), MC label; per TF: TFIDInfo and vDrift / t0 of the TPC transformation. Only raw detector data are stored: TPC transformation,
  TOF calibration, ITS dictionary and geometry are applied offline.
- TPC road: each leg's helix through all pad rows of its side, in the frame of its own time0, at the real x of the row, points beyond
  the leg's closest approach skipped; predicted real (y, z) mapped to nominal coordinates with the inverse correction; clusters within
  --corridor-width (1 cm) taken. The other TPC side is searched when the time of the cosmic is known (CE-crossing leg, z-continuity
  time with error < --max-abs-time-err 0.5 mus, or a TOF time).
- TOF tag: all TOF clusters within the cosmic's time window and the road (--tof-road-width 5 cm) are candidates per leg; the top/bottom
  pair whose time difference matches the muon's flight along the helix (|t_top - t_bottom + L/c| < --tof-flight-tolerance 2 ns, z of
  one-side legs shifted to the pair's mean time) gets HitTOFFlight and the cosmic its TOF time (CosmicTrack::timeTOFMUS); without such a
  pair the closest hit per leg is kept. The same search in the impossible order (bottom hit first) only finds accidental pairs: its
  best score is stored next to the flagged pair's (scoreTOFPair / scoreTOFReversed) as QA of the flag's background.
- The TOF time (--tof-time-error 0.1 mus) then fixes the other-side TPC corridor, the TRD road (trigger and z, --trd-road-width) and the
  ITS road (readout frame and z, --its-road-width); without it the TPC time is used.
- Duplicates: per TF the cosmics are ranked (TOF time first, then more attached TPC clusters); one sharing >= 30 % of the smaller one's
  TPC clusters with a better one gets duplicateOf = that one's entry (a leg split into two TPC tracks). Nothing is removed.
- Polish: cosmics with a TOF time are refitted at it (TPC-only legs: bottom leg inward to the closest approach to the beam line, top
  leg inward to the same point, halves combined; muon mass and energy loss along the flight as in the matcher), CosmicTrack::polished
  with chi2MatchPolished (< 0: not polished). The matcher's time is the bracket-overlap centre for one-side legs on the same side
  (tens of mus off), which puts the inner material at the wrong z. Check: polished at the matcher's time instead, the cosmic MC
  reproduces the matcher (chi2Match median 79.1 vs 79.2, q/pt within 7e-4).
- Legs nearly parallel to the pad rows (closest approach to the beam line inside the TPC or at its inner edge): the row-by-row road
  cannot reach the rows, there the helix is followed in steps of path length and the rows within the road width are searched.
- A TOF time can be negative (cosmic just before the TF start): the flag is CosmicTrack::hasTOFTime() (scoreTOFPair >= 0).
- At most --max-cosmics-per-tf (100) cosmics per TF are written (protection against fake-dominated settings).
- --debug-tree: cosmics_collector_debug.root, tree "cosmics" with one entry per cosmic (matching and timing quantities, vectors of the
  transformed TPC clusters, road points, ITS / TOF / TRD hits). Off by default.

Validation: the road re-finds 99.8 % of the legs' own clusters in the cosmics run 562658 and 97 % in PbPb 2025 with the v10n correction
map. PbPb 2025 LHC25an 567939 (600 TFs, preset physics-v1): 30 of 224 cosmics TOF-tagged (10 with legs on opposite TPC sides, 20 on one
side), 0 pairs in the impossible order (flag purity >= 90 % at 95 % CL), flight-time residual centred at 0 within 0.2 ns; 10 duplicates.
568041 reconstructed from CTF (10546 TFs): 3203 cosmics, 435 TOF-tagged non-duplicates, 90 duplicates. CPU: matcher + collector
~0.6 s per PbPb TF; output ~1.5 kB per TF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
matthias-kleiner and others added 2 commits October 8, 2026 16:04
A TPC-only track has no time measurement: its time0 is the tracker's guess
(GPUTPCGMTrackParam::ShiftZ: z = 0 at the beam line if the helix can come
from it, otherwise the latest cluster at z = 0.521 * x, then clamped to the
drift volume). For a cosmic, which does not come from the beam line, the
two legs get independent guesses, typically tens of mus apart, so their
clusters were distortion-corrected at different z and the legs disagree
(y, snp, q/pt) although they are one track. For legs on opposite sides the
time comes from z continuity, but legs on the same side were compared as
tracked.

New MatchCosmicsParams refitSameSideAtCommonTime (default false, not in
the preset physics-v1, see below): after the cheap cuts (tgl, q/pt, same half), same-side
TPC-only legs are refitted at the centre of their brackets' overlap (the
time the refit of the winners uses) and compared there
(MatchCosmics::refitSeedAtTime: TPC refit from the outer parameters, then the
propagation to the DCA as for the seeds; energy loss along the muon's flight
as in refitWinners). The TPC refitter is created once per TF in process() and
shared with refitWinners. The matcher debug tree writes the legs compared
and a commonTime flag.

Cosmic MC with PbPb-like distortions (190 TFs, preset physics-v1, off -> on):
correctly matched muons 6848 -> 7324 of 8639 (79.3 -> 84.8 %); same side
77.0 -> 84.2 %, its loss to the crude chi2 cut 6.9 -> 0.8 %; A×C unchanged;
0 wrong-muon pairs in both; matcher +12 ms per TF (~100 refits). With the
true MC time instead of the window centre the same-side pass rate of the
chi2 cut would be 99.2 % (centre 98.0 %, legs at their own time0s 84.7 %).
PbPb 2025 (4 TFs): ~530 refits per TF, +15 ms per TF.

Not in the preset: in PbPb (568041, 310 CTFs, 16541 TFs) it adds mostly
pairs of collision tracks, whose time0 was about right and which the
refit at the window centre mis-corrects: +352 same-side cosmics but only
+5 TOF-tagged (2.6 % of the new ones vs 15.3 % of the common ones), and
~35 A×C cosmics lose a leg to a refitted same-side pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New MatchCosmicsParams tofFlightSelection (default off, on in the preset
physics-v1; needs TOF clusters, the workflow then adds them to the
matcher's inputs): every pair of TPC-only legs accepted by checkPair is
tested for a top / bottom TOF cluster pair along the outward
continuations of its legs whose time difference matches the muon's
flight between them along the helix (tofFlightTolerance), with the mean
time in the pair's time window and both legs' y and z within tofRoad at
that time (the test of the cluster collector). A confirmed pair takes
the TOF time as its common time (error tofTimeError), so the winner is
refitted at it, and is put in front of all unconfirmed partners of both
legs (chi2 order within each group): the mutual-best selection prefers
it, and a random pair can no longer take a leg of a TOF-confirmed cosmic.

If the refit of a confirmed winner at the TOF time fails (in practice
chi2Match > maxChi2Match), it is refitted at the time it has without its
TOF flight pair (z-continuity time of legs on opposite sides, else the
centre of the overlap of the legs' time brackets): the winner selection
has already released the other candidates of both legs, so dropping the
winner loses both legs. PbPb 568041: 24 TOF-tagged same-side cosmics,
all real (legs on one line far from the beam line, TOF pair in the
physical order without a reversed-order alternative), mostly on the C
side nearer the readout at the TOF time; A-C cosmics show no TOF-TPC
time offset there. The refit loop body is a lambda refitting a winner at
a given time.

The TOF candidates of a leg are searched once per TF, in the time-sorted
TOF clusters of its time bracket and in the sector it points to and its
neighbours. Debug tree "match": tofScore.

Distorted cosmic MC (19 x 10 TFs, PbPb-like distortions, physics-v1
without the common-time refit, without -> with tofFlightSelection):
matched muons 6848 -> 6871 of 8639, 0 wrong pairs both, 2134 confirmed
pairs, 9 fallbacks.

PbPb 568041 reconstructed from CTF (310 CTFs, 16541 TFs, vs. the same
CTFs without the TOF selection, older code, before the fallback):
cosmics 4782 -> 4760, TOF-tagged 681 -> 697; A-C: 11 untagged pairings
replaced by 12 TOF-tagged ones. Matcher CPU 0.536 -> 0.545 s per TF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matthias-kleiner
matthias-kleiner force-pushed the cosmics-matcher-writer-clean branch from 18a44b6 to 9a493f4 Compare October 8, 2026 14:04
…in async

With CALIB_ASYNC_EXTRACTCOSMICS=1 (set by O2DPG from the JDL), the async
calibration workflows add o2-cosmics-match-workflow on the TPC-only tracks
with the preset COSMICS_PRESET (default physics-v1) and the raw-cluster
output (o2_cosmics_full.root, always written, as the TPC time series).
The road detectors are those of ITS, TOF, TRD reconstructed in the job;
without TOF the preset's TOF flight selection is switched off.

Checked in print mode with the O2DPG counterpart: the switch adds only this
workflow; no workflow without TPC, in sync mode, or with the switch unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@shahor02 shahor02 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good as far as I could follow w/o running with AI over it. A small cosmetic comment: the CosmicTrack containing TrackCosmic might be confusing, could you ask Claude to rename it, e.g. to TrackCosmicExtended or something like that?

// the common-time refit of same-side legs (refitSameSideAtCommonTime) is not used: in PbPb it added mostly collision-track pairs
static const std::map<std::string, std::string> presets{
{"physics-v1",
"cosmicsMatch.minSeedPt=1;cosmicsMatch.minSeedDCAxy=3;cosmicsMatch.minSeedDCAxyNSigma=10;cosmicsMatch.minSeedNClTPC=30;"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would not 3cm cut damage ITS IB coverage?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shahor02 , yes, you are right. With this cut we lose the cosmics crossing the IB. I am running a test on GSI to see whether a lower cut is feasible in PbPb (CPU and fake pairs).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shahor02 , simply lowering these cuts is not feasible in PbPb: already at 1 cm / 3σ the number of cosmic candidates grows by ~40×, almost all of them pairs of tracks from one collision. Instead I added looser selections, minSeedDCAxyTOF and minSeedDCAxyNSigmaTOF (off by default): a TPC leg that fails the standard selection but passes these is only used if the cosmic candidate has a top/bottom TOF hit pair matching the cosmics flight time. Such cosmics are flagged (TrackCosmics::NearBeamBottom/NearBeamTop) so they can be selected or dropped downstream. Additionally, the collector now keeps the 5 closest ITS clusters per leg in each inner-barrel layer, so the ITS clusters can be used offline to reject the remaining fake candidates. With the option switched on, the output grows by ~50 % and the matcher time roughly doubles, to ~1.1 s per TF, so it should be still fine.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sens. BTW, you could reduce the combinatorics by flagging in advance the TPC tracks with participate in the global tracks - contributors to any PV.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, its implemented. TPC tracks belonging to a PV contributor are now rejected as cosmic legs (--pv-contributor-sources set automatically from $VERTEXING_SOURCES). On 600 TFs of 567939 this keeps all physics-v1 cosmics and reduces the matcher CPU time by 21 % (by 50 % with the looser near-beam selection).

@matthias-kleiner
matthias-kleiner requested a review from a team as a code owner October 8, 2026 15:29
The per-cosmic output of the cluster collector contains the matcher's
TrackCosmics plus the raw hits of its legs; the new name makes that
relation explicit (review comment). Header CosmicTrack.h is now
TrackCosmicsExtended.h; content and branch names are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alibuild

alibuild commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Error while checking build/O2/fullCI_slc9 for 22bdf41 at 2026-10-09 07:59:

## sw/BUILD/o2codechecker-latest/log
100% tests passed, 0 tests failed out of 1


## sw/BUILD/ThePEG-latest/log
collect2: error: ld returned 1 exit status


## sw/BUILD/O2-full-system-test-latest/log
command /sw/slc9_x86-64/O2/slc9_x86-64-slc9_x86-64-local6/prodtests/full-system-test/dpl-workflow.sh had nonzero exit code 1


## sw/BUILD/o2checkcode-latest/log
--
========== List of errors found ==========
++ GRERR=0
++ grep -a -v clang-diagnostic-error error-log.txt
++ grep -a ' error:'
++ GRERR=1
++ [[ 1 == 0 ]]
++ mkdir -p /sw/INSTALLROOT/859a911b514aafd2ca198d66670b86334a33628f/slc9_x86-64/o2checkcode/1.0-local15/etc/modulefiles
++ alibuild-generate-module
+ HAS_BIN=
+ HAS_LIB=
+ HAS_CMAKE=
+ HAS_ROOT=
+ '[' 0 '!=' 0 ']'
+ cat
+ printf 'if ![ is-loaded '\''BASE/1.0'\'' ] {\n module load BASE/1.0\n}'
+ echo 'BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release'
BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release
+ FULL_BUILD_REQUIRES='alibuild-recipe-tools bz2 safe_int UUID defaults-release O2-customization Alice-GRID-Utils double-conversion ninja-fortran json-c ninja MPFR googlebenchmark CMake Python-modules-list pytorch_cpuinfo FairCMakeModules date'
+ echo 'FULL_BUILD_REQUIRES=alibuild-recipe-tools bz2 safe_int UUID defaults-release O2-customization Alice-GRID-Utils double-conversion ninja-fortran json-c ninja MPFR googlebenchmark CMake Python-modules-list pytorch_cpuinfo FairCMakeModules date'
FULL_BUILD_REQUIRES=alibuild-recipe-tools bz2 safe_int UUID defaults-release O2-customization Alice-GRID-Utils double-conversion ninja-fortran json-c ninja MPFR googlebenchmark CMake Python-modules-list pytorch_cpuinfo FairCMakeModules date
++ env
++ cut -f1 -d=
++ grep -v '^DEFAULT_'
++ grep -v PKGREVISION
++ grep -v ALIBUILD_RECIPE_TOOLS
++ grep REVISION
++ sed -e s/_REVISION//
+ for x in $(env | cut -f1 -d= | grep -v "^DEFAULT_" | grep -v PKGREVISION | grep -v ALIBUILD_RECIPE_TOOLS | grep REVISION | sed -e 's/_REVISION//')
++ eval 'echo $LIBFFI_REVISION'
+++ echo 14
+ REVISION_VALUE=14
++ eval 'echo $LIBFFI_VERSION'
+++ echo v3.2.1-alice1
+ VERSION_VALUE=v3.2.1-alice1
++ eval 'echo $LIBFFI_ROOT'
[0 more errors; see full log]

Full log here.

matthias-kleiner and others added 2 commits October 9, 2026 12:14
The seed cuts minSeedDCAxy / minSeedDCAxyNSigma (3 cm / 10 sigma in
physics-v1) reject the legs of collision tracks, but also the cosmics
crossing the ITS inner barrel (L0 / L1 entirely, L2 mostly). Loosening
them floods the matcher with collision-track pairs (PbPb 567939, 600 TFs:
1 cm / 3 sigma gives 38x more candidates, TOF-tagged 0.1 % vs 14 %).

New MatchCosmicsParams minSeedDCAxyTOF (default -1: off) and
minSeedDCAxyNSigmaTOF (3): with tofFlightSelection, TPC-only legs failing
the seed DCA cuts but passing these looser ones are kept, flagged nearBeam,
and used in TOF-confirmed pairs only: a pair with such a leg and no TOF
flight pair is rejected (RejNoTOF) before it is registered, so it cannot
compete in the winner selection or reach the cluster collector. Log line:
seeds near the beam line and their confirmed pairs per TF.

The cosmics carry TrackCosmics flags NearBeamBottom / NearBeamTop (new
member, class version 2) for legs kept only by the looser cuts, so these
cosmics can be selected or dropped downstream without redoing the seed
cuts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ner-barrel layer

Near the beam line the road in the inner barrel is dense with collision
clusters, and the TPC prediction there (~mm) does not single out the
cosmic's hit: keeping only the closest cluster per half of the cosmic and
layer often stores a random one. In layers 0-2 the 5 closest are now
kept, best first (the first is the previous choice); the outer barrel
keeps the closest. The insertion rejects a NaN score, as the single-hit
comparison did. Only cosmics with |DCA_xy| < 3.8 cm cross the inner
barrel, so the output grows only for those.

PbPb 568041, 400 CTFs with near-beam legs (minSeedDCAxyTOF=0): first road
hit of every (cosmic, half, layer) identical to the previous code, outer
barrel unchanged, output +1.8 %. On near-beam tracks fitted in the outer
barrel, 24 of the 31 inner-barrel hits on the track are not the closest
road hit (the ranking is dominated by the z uncertainty).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alibuild

alibuild commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Error while checking build/O2/fullCI_slc9 for 3f1d9f8 at 2026-10-09 17:02:

## sw/BUILD/o2codechecker-latest/log
100% tests passed, 0 tests failed out of 1


## sw/BUILD/ThePEG-latest/log
collect2: error: ld returned 1 exit status


## sw/BUILD/O2-full-system-test-latest/log
command /sw/slc9_x86-64/O2/slc9_x86-64-slc9_x86-64-local12/prodtests/full-system-test/dpl-workflow.sh had nonzero exit code 1


## sw/BUILD/o2checkcode-latest/log
--
========== List of errors found ==========
++ GRERR=0
++ grep -a -v clang-diagnostic-error error-log.txt
++ grep -a ' error:'
++ GRERR=1
++ [[ 1 == 0 ]]
++ mkdir -p /sw/INSTALLROOT/27063cfef39f318b3e838961e5d45d4edf9c7a64/slc9_x86-64/o2checkcode/1.0-local17/etc/modulefiles
++ alibuild-generate-module
+ HAS_BIN=
+ HAS_LIB=
+ HAS_CMAKE=
+ HAS_ROOT=
+ '[' 0 '!=' 0 ']'
+ cat
+ printf 'if ![ is-loaded '\''BASE/1.0'\'' ] {\n module load BASE/1.0\n}'
+ echo 'BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release'
BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release
+ FULL_BUILD_REQUIRES='json-c Alice-GRID-Utils Python-modules-list alibuild-recipe-tools MPFR UUID pytorch_cpuinfo date ninja ninja-fortran defaults-release CMake safe_int googlebenchmark bz2 double-conversion O2-customization FairCMakeModules'
+ echo 'FULL_BUILD_REQUIRES=json-c Alice-GRID-Utils Python-modules-list alibuild-recipe-tools MPFR UUID pytorch_cpuinfo date ninja ninja-fortran defaults-release CMake safe_int googlebenchmark bz2 double-conversion O2-customization FairCMakeModules'
FULL_BUILD_REQUIRES=json-c Alice-GRID-Utils Python-modules-list alibuild-recipe-tools MPFR UUID pytorch_cpuinfo date ninja ninja-fortran defaults-release CMake safe_int googlebenchmark bz2 double-conversion O2-customization FairCMakeModules
++ env
++ cut -f1 -d=
++ grep -v '^DEFAULT_'
++ grep -v PKGREVISION
++ grep -v ALIBUILD_RECIPE_TOOLS
++ grep REVISION
++ sed -e s/_REVISION//
+ for x in $(env | cut -f1 -d= | grep -v "^DEFAULT_" | grep -v PKGREVISION | grep -v ALIBUILD_RECIPE_TOOLS | grep REVISION | sed -e 's/_REVISION//')
++ eval 'echo $LIBFFI_REVISION'
+++ echo 14
+ REVISION_VALUE=14
++ eval 'echo $LIBFFI_VERSION'
+++ echo v3.2.1-alice1
+ VERSION_VALUE=v3.2.1-alice1
++ eval 'echo $LIBFFI_ROOT'
[0 more errors; see full log]

Full log here.

matthias-kleiner and others added 3 commits October 9, 2026 19:40
Review suggestion: a TPC track that is part of a global track contributing
to a primary vertex comes from a collision, not from a cosmic. The existing
veto (--use-pv-info with cosmicsMatch.discardPVContributors, default on)
compared the contributor's own track ID with the seeds, so it never fired
for TPC-only legs: the contributors are ITS-TPC and higher.

New workflow option --pv-contributor-sources (implies --use-pv-info,
ignored with a warning if discardPVContributors is off): the contributors
of these global track sources reject every leg they contain
(RecoContainer::getSingleDetectorRefs), e.g. their TPC track. The sources
and the parent matches needed to resolve them are loaded only for this;
the legs still come from --track-sources only. Log line: seeds rejected
per TF (also those that are themselves contributors).

PbPb 567939, 2 TFs with vertices (94 each), sources ITS-TPC,ITS-TPC-TRD,
ITS-TPC-TOF,ITS-TPC-TRD-TOF: 54 % of the TPC seeds rejected; without seed
DCA cuts the collision-track pairs drop from 183 / 285 to 58 / 88 per TF,
with the near-beam option the near-beam seeds by 57 %; matcher CPU for the
4 TFs (2 of them without vertices) 3.1 -> 2.3 s; the physics-v1 cosmic is
kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With CALIB_ASYNC_EXTRACTCOSMICS=1 the cosmics matcher gets
--pv-contributor-sources $VERTEXING_SOURCES when the primary vertexing
runs, as the time series gets $TRACK_SOURCES: the TPC part of a vertex
contributor is no cosmic leg. COSMICS_PV_VETO=0 switches it off,
COSMICS_PV_SOURCES overrides the sources. The option ignores sources
without TPC, so the vertexing sources are passed as they are (help text).

Checked in print mode (veto on / off, without ITS: TPC-TOF) and on 4 PbPb
TFs with the full vertexing source list: the same seeds rejected as with
the 4 ITS-TPC sources that have contributors there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With --track-sources containing ITS-TPC (or another source with ITS) but
not ITS, the matcher's winner refit and the cluster collector read the ITS
track of such a leg (getITSTrack, its cluster references), which was
neither requested nor read: segfault in refitWinner, then in the
collector; without an ITS road there was also no ITS cluster reader
(invalid workflow). The ITS tracks and clusters are now requested and read
for these legs, without making standalone ITS tracks legs (seed sources
unchanged). TPC-only legs (physics-v1 in async) are not affected.

PbPb 567939, 4 TFs, --track-sources TPC,ITS-TPC: all TFs processed with
and without the ITS road (crash before), no ITS-only legs (seeds 23318
vs 26345 with ITS as legs); TPC-only legs: unchanged, no ITS track reader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alibuild

alibuild commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Error while checking build/O2/fullCI_slc9 for 7803bcf at 2026-10-10 01:37:

## sw/BUILD/o2codechecker-latest/log
100% tests passed, 0 tests failed out of 1


## sw/BUILD/ThePEG-latest/log
collect2: error: ld returned 1 exit status


## sw/BUILD/O2-full-system-test-latest/log
command /sw/slc9_x86-64/O2/slc9_x86-64-slc9_x86-64-local4/prodtests/full-system-test/dpl-workflow.sh had nonzero exit code 1


## sw/BUILD/o2checkcode-latest/log
--
========== List of errors found ==========
++ GRERR=0
++ grep -a -v clang-diagnostic-error error-log.txt
++ grep -a ' error:'
++ GRERR=1
++ [[ 1 == 0 ]]
++ mkdir -p /sw/INSTALLROOT/9351f68695656aa5678f348cbbd683196541e75e/slc9_x86-64/o2checkcode/1.0-local9/etc/modulefiles
++ alibuild-generate-module
+ HAS_BIN=
+ HAS_LIB=
+ HAS_CMAKE=
+ HAS_ROOT=
+ '[' 0 '!=' 0 ']'
+ cat
+ printf 'if ![ is-loaded '\''BASE/1.0'\'' ] {\n module load BASE/1.0\n}'
+ echo 'BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release'
BUILD_REQUIRES=CMake alibuild-recipe-tools defaults-release
+ FULL_BUILD_REQUIRES='MPFR json-c FairCMakeModules UUID ninja Alice-GRID-Utils ninja-fortran safe_int bz2 alibuild-recipe-tools CMake Python-modules-list defaults-release O2-customization date googlebenchmark double-conversion pytorch_cpuinfo'
+ echo 'FULL_BUILD_REQUIRES=MPFR json-c FairCMakeModules UUID ninja Alice-GRID-Utils ninja-fortran safe_int bz2 alibuild-recipe-tools CMake Python-modules-list defaults-release O2-customization date googlebenchmark double-conversion pytorch_cpuinfo'
FULL_BUILD_REQUIRES=MPFR json-c FairCMakeModules UUID ninja Alice-GRID-Utils ninja-fortran safe_int bz2 alibuild-recipe-tools CMake Python-modules-list defaults-release O2-customization date googlebenchmark double-conversion pytorch_cpuinfo
++ env
++ cut -f1 -d=
++ grep -v '^DEFAULT_'
++ grep -v ALIBUILD_RECIPE_TOOLS
++ grep -v PKGREVISION
++ grep REVISION
++ sed -e s/_REVISION//
+ for x in $(env | cut -f1 -d= | grep -v "^DEFAULT_" | grep -v PKGREVISION | grep -v ALIBUILD_RECIPE_TOOLS | grep REVISION | sed -e 's/_REVISION//')
++ eval 'echo $LIBFFI_REVISION'
+++ echo 14
+ REVISION_VALUE=14
++ eval 'echo $LIBFFI_VERSION'
+++ echo v3.2.1-alice1
+ VERSION_VALUE=v3.2.1-alice1
++ eval 'echo $LIBFFI_ROOT'
[0 more errors; see full log]

Full log here.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants