Skip to content

Support (staggered) per-layer cluster input in ITS/TPC matching - #15869

Open
shahor02 wants to merge 3 commits into
AliceO2Group:devfrom
shahor02:pr_recocontNUSE
Open

shahor02 wants to merge 3 commits into
AliceO2Group:devfrom
shahor02:pr_recocontNUSE

Conversation

@shahor02

Copy link
Copy Markdown
Collaborator

No description provided.

shahor02 and others added 2 commits September 29, 2026 21:47
Extend MatchTPCITS to work with ITS clusters provided either as a single
(monolithic) input or per layer, with layer-dependent ROF length and bias
(staggered readout):

- ITS clusters, sizes, cluster ROFRecords and MC labels are stored per
  layer, clusters are addressed by the composed ID (layer<<28)+index_in_layer
  (all in slot 0 for the monolithic input)
- all ITS ROF timings (per-layer lengths and biases in BC and mus, the clock
  layer defining the ITS tracks ROFs granularity) are derived from the
  DPLAlpideParam object set via setAlpideParam; the setITSROFrameLength...
  and setITSTimeBiasInBC setters are removed
- interaction candidates are related to the cluster ROFs of every AfterBurner
  layer within the optional abROFMarginMUS margin (allowing up to 2 compatible
  ROFs per layer) and are cut at the last clock-layer cluster ROF
- AfterBurner reworked for CPU efficiency: unused clusters are filtered and
  (chip,Z)-sorted once per TF into per (layer, ROF) blocks, built only for the
  ROFs referenced by candidates with seeds; ITSChipClustersRefs is replaced by
  thread-local per-layer views (compact Y,Z,id,chip cluster info) refreshed
  only when the processed group of candidates changes ROFs
- tpcits-match-workflow can request the per-layer ITS clusters input
  (through RecoContainer::setITSPerLayer)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hing

MatchTPCITS previously assigned every ITS track the full clock-layer ROF
duration as its time bracket. TrackITS now carries a per-track TimeStamp
(BC since TF start, symmetric error, ROF bias already applied), which is
typically much narrower than the ROF, especially in staggered running.

- prepareITSData builds the per-track bracket from getTimeStamp(), widened
  by the new itsTimeStampMarginBC margin (BC, both edges), falling back to
  the nominal ROF bracket when the time stamp is invalid (legacy input)
- mITSROFTimes is extended to the envelope of the nominal ROF bracket and
  the actual per-track brackets, keeping the TPC-side and triggered-mode
  ITS ROF entry caches conservative
- mITSMaxROFOverhangMUS tracks how far track brackets extend past their
  ROF end in the current TF; doMatching's continuous-mode entry lookup is
  shifted by this amount so no compatible track is skipped
- sorting by bracket min time still cannot mix tracks of different ROFs
  (the tracker guarantees the raw lower edge stays within the assigned
  ROF, and the margin shifts all tracks alike), so the existing
  mITSTimeStart assignment and the tBracket-based break/continue gates in
  doMatching remain valid without a LUT rebuild; the long-dead RejectOnTgl
  ROF-skip code (whose precondition never held with mixed layers) is
  removed
- refitTrackTPCITS derives the fallback ITS time error from the track's
  own bracket (delta()/sqrt(12)) instead of the nominal clock-layer ROF
  resolution

Net effect: most TPC x ITS pairs are now rejected by the cheap bracket
overlap check in doMatching before the sqrt/kinematic comparisons, with no
new containers and a single extra float member.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
With the per-layer (staggered readout) ITS clusters input the cluster index kept
by TrackITS is local to its layer, so the layer must be encoded into the stored
reference for the consumers to be able to find the cluster. MatchTPCITS already
decoded the ITS/TRACKCLSID entries as such composed IDs, but the tracker pushed
the bare per-layer index, which was correct only for the layer 0.

- ITSTrackingInterface::run composes the stored reference as
  (layer << ClusLayerShift) + index_in_layer; with the monolithic clusters input
  the layer slot is 0 and the composed ID stays equal to the flat index, so the
  non-staggered output is unchanged
- the ID composition/decomposition and the max number of separately provided
  ITS/MFT cluster layers move from MatchTPCITS.h to the new lightweight
  DataFormatsITSMFT/ClusterID.h, so that both the producer and the (many)
  consumers can use them without pulling in GlobalTracking; RecoContainer.h
  includes it and keeps MaxITSLayers/MaxMFTLayers as aliases
- the layer field is shifted by 27 rather than 28 bits, so that it can
  accommodate the MFT layers too: the bit 31 is unusable, since the negative
  values of the composed ID are reserved for the "no cluster" flags
- the unused TrackITSExt::setClusterIndex, carrying its own hardcoded copy of
  the composition (and writing to the packed slot while getClusterIndex reads
  the layer slot), is removed

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

Copy link
Copy Markdown
Collaborator Author

@mpuccio @f3sch Contrary to what I thought, the compound indices ((lr<<28)+idx)) in case of staggering were used in the ITS tracking only internally, but were not exported to ITS track cluster references.
I've changed this in the last 1472563, also using it for encoding of TPCITS AB cluster refs.
To allow its usage for MFT also, I've modified it to ((lr<<27)+idx)), please protest if you think this may create problems.

@f3sch

f3sch commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

@mpuccio @f3sch Contrary to what I thought, the compound indices ((lr<<28)+idx)) in case of staggering were used in the ITS tracking only internally, but were not exported to ITS track cluster references. I've changed this in the last 1472563, also using it for encoding of TPCITS AB cluster refs. To allow its usage for MFT also, I've modified it to ((lr<<27)+idx)), please protest if you think this may create problems.

Sorry I may misunderstand but why is <<27 needed for MFT should not <<28 shift give you already 0-15 range?
Otherwise this is of course fine (excited for the results).

@shahor02

Copy link
Copy Markdown
Collaborator Author

Sorry I may misunderstand but why is <<27 needed for MFT should not <<28 shift give you already 0-15 range?
Otherwise this is of course fine (excited for the results).

@f3sch these IDs are signed ints and the negative values are used internally as flags. But even with 27 we still have more than enough room to accommodate all clusters: at 50kH PbPb we have <5M clusters, we can accommodate 134M?

@f3sch

f3sch commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Sorry I may misunderstand but why is <<27 needed for MFT should not <<28 shift give you already 0-15 range?
Otherwise this is of course fine (excited for the results).

@f3sch these IDs are signed ints and the negative values are used internally as flags. But even with 27 we still have more than enough room to accommodate all clusters: at 50kH PbPb we have <5M clusters, we can accommodate 134M?

Ah ok, thanks. Indeed more than enough headroom.

@alibuild

Copy link
Copy Markdown
Collaborator

Error while checking build/O2/fullCI_slc9 for 1472563 at 2026-09-30 22:51:

No log files found

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