Skip to content

Reco Particle ‐ Lower object architecture sketch

Jeremy Wolcott edited this page Feb 10, 2026 · 4 revisions

This is a design sketch of how to implement a SRRecoParticle-to- mapping, as described in #23. It consists of 4 major components.

Introduce base class for low-level reco objects

Just as in branch feature/reco_linkage, every low-level reco object (SRTrack, SRShower, SRECalCluster, ...) needs to become a subclass of a SRRecoObjBase. The commit 4d74e0c from that branch makes this an empty class. However, we can also add another "back-reference" field to it so that the low-level object can point back to the SRRecoParticle. This would entail:

  • Introducing a class RecoParticleID into SREnums.h, in analogy to TrueParticleID, containing fields:
    • the SRInteraction index
    • An enum corresponding to top-level SRRecoParticle collections (Pandora, DLP/SPINE, SAND reco)
    • the SRRecoParticle index
  • Adding a field to the SRRecoObjBase that consists of a RecoParticleID instance

Introduce SRRecoBaseID

This class will be very like the SRRecoParticleID from the previous bullet, except its job is to identify which collection of underlying reco objects the target object lives in.
There are lots of possibilities, which will make it rather tedious to enumerate them all, but after a lot of reflection (see discussion at #23 I don't think there's another way to do it. The enum will have entries like

...
kFDPandoraTrack,
KFDPandoraShower,
...
kNDLArDLPTrack,
kNDLArDLPShower,
kNDLArPandoraTrack,
kNDLARPandoraShower,
...
kTMSTrack,
...
kSANDTrack,
kSANDShower,
kSANDECalCluster,
...

Extend SRRecoParticle

  • Obviously a new field containing a SRRecoBaseID will need to be added to SRRecoParticle.
  • At the same time, the current field origRecoObjType (and its corresponding enum RecoObjType) will need to be extended to have an entry for all possible reco object types enumerated in the previous bullet.

Build functions to expedite lookup

These new classes will be a pain for users to actually use, so it's best to build some functions to traverse the hierarchy for them. There are examples of this sort of thing already for truth-matching: https://github.com/DUNE/duneanaobj/blob/main/duneanaobj/StandardRecord/Navigate.h#L18-L25

We'll need

  • a const SRRecoParticle * FindRecoParticle(const StandardRecord & sr, const RecoParticleID& partid) (which is intended to be used with the new field added to SRRecoObjBase in the first bullet)
  • a const SRRecoObjBase * FindRecoObjBase(const StandardRecord & sr, const SRRecoBaseID& baseid) (which is intended to be used with the new field added to SRRecoParticle in the second bullet)

Users of the second signature will then need to dynamic_cast<> the resulting pointer to the actual type they expect (SRTrack, etc.). The origRecoObjType field should help them decide whether they want to do that.