Adding DLShowerMatching algorithms - #288
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new deep-learning-driven multi-view cluster matching workflow (DLMultiViewMatchingAlgorithm) and supporting “clear”/“merge-and-create” tools to build 3D shower-like PFOS from connected multi-view cluster groups. It also extends geometry/hit metadata to support wire-overlap logic and hit feature extraction for model inference/training.
Changes:
- Introduces
DLMultiViewMatchingAlgorithmplus 2-view/3-view matching tools to create PFOS from connected cluster groups using learned similarity scores. - Adds
LArDLShowerHelperfor per-hit feature calculation used in matching/training. - Extends
LArCaloHitand geometry helpers to provide plane/wire/intersection metadata and detector drift-gap boundaries needed by the new matching logic; wires new sources into build/registration.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLTwoViewMergeAndCreateShowersTool.h | Declares 2-view ambiguous-group merging/seed selection tool. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLTwoViewMergeAndCreateShowersTool.cc | Implements 2-view ambiguous-group seed selection and merging logic. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLTwoViewClearShowersTool.h | Declares 2-view clear (0:1:1 etc.) PFO creation tool. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLTwoViewClearShowersTool.cc | Implements 2-view clear-group PFO creation. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLThreeViewMergeAndCreateShowersTool.h | Declares 3-view ambiguous-group merging/seed selection tool. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLThreeViewMergeAndCreateShowersTool.cc | Implements 3-view ambiguous-group seed selection and merging logic. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLThreeViewClearShowersTool.h | Declares 3-view clear (1:1:1) PFO creation tool. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLThreeViewClearShowersTool.cc | Implements 3-view clear-group PFO creation. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLMultiViewMatchingAlgorithm.h | Declares the main multi-view matching algorithm, data structures, and tool interface. |
| larpandoradlcontent/LArThreeDReco/LArShowerMatching/DLMultiViewMatchingAlgorithm.cc | Implements navigation building, overlap logic, model inference/training output, and tool execution loop. |
| larpandoradlcontent/LArHelpers/LArDLShowerHelper.h | Declares hit-feature helper used by DL shower matching/growing. |
| larpandoradlcontent/LArHelpers/LArDLShowerHelper.cc | Implements hit feature extraction (relative coords, gap distance, energy, etc.). |
| larpandoradlcontent/LArDLContent.cc | Registers the new algorithm and tools with the DL content factory. |
| larpandoracontent/LArObjects/LArCaloHit.h | Extends hit parameters/object and IO with plane/wire/intersection ranges needed for overlap logic. |
| larpandoracontent/LArHelpers/LArGeometryHelper.h | Adds API to expose detector drift-gap x boundaries. |
| larpandoracontent/LArHelpers/LArGeometryHelper.cc | Implements drift-gap x boundary extraction from geometry gap list. |
| cmake/LArDLContent_sources.cmake | Adds new sources to the DL content build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (m_version > 3) | ||
| { | ||
| PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, xmlFileWriter.WriteVariable("Plane", pLArCaloHit->GetPlane())); | ||
| PANDORA_RETURN_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, xmlFileWriter.WriteVariable("WireId", pLArCaloHit->GetWireId())); |
AndyChappell
left a comment
There was a problem hiding this comment.
Mostly trivial comments, a few more substantive, and one in need of more serious discussion (LArCaloHit extension).
| pandora::InputUInt m_plane; ///< The plane id | ||
| pandora::InputUInt m_wireId; ///< The wire id (only unique to daughter volume) | ||
| pandora::InputUInt m_plane1; ///< The first projection plane id | ||
| pandora::InputUInt m_minIntersectWire1; ///< The id of the first (lowest wire id) intersecting wire (in proj plane 1) | ||
| pandora::InputUInt m_maxIntersectWire1; ///< The id of the last (highest wire id) intersecting wire (in proj plane 1) | ||
| pandora::InputUInt m_plane2; ///< The second projection plane id | ||
| pandora::InputUInt m_minIntersectWire2; ///< The id of the first (lowest wire id) intersecting wire (in proj plane 2) | ||
| pandora::InputUInt m_maxIntersectWire2; ///< The id of the last (highest wire id) intersecting wire (in proj plane 2) |
There was a problem hiding this comment.
We can discuss timing and milestone requirements etc, but, I think in reality, we would want the wireId (and somewhat (also time tick would be useful, but obviously not directly relevant to this work), but everything else belongs in a new geometry object that should keep track of these geometry- rather than hit-relative quantities, given that this is a lot of overhead on hits for quantities that aren't unique to the hit (and you know the knock on effects this has on persistency, pending an overhaul of that). I agree, this would require an SDK update - but I think we should do that.
That said, from this point forward, I'll review the code under the assumption this is all fine.
| * | ||
| * @return the plane id | ||
| */ | ||
| unsigned int GetPlane() const; |
There was a problem hiding this comment.
Partly a note to myself - why do we need plane id, given we already have HitType?
There was a problem hiding this comment.
Think we've spoken about this, but just for completeness it's due to the wrapping of wires in DUNE HD FD - so U&V pandora view wires (on opposite sides of the APA) correspond to the same plane
| unsigned int GetWireId() const; | ||
|
|
||
| /** | ||
| * @brief Get the first projection plane id |
There was a problem hiding this comment.
What constitutes the "first" plane in this context?
There was a problem hiding this comment.
just one of the 'other' views. There's some ordering to this though. So if your wire is U then 1st and 2nd are V & W respectively, V -> W(1)U(2), W -> U(1)V(2).
But this will change to use the new geom functionality.
AndyChappell
left a comment
There was a problem hiding this comment.
A couple of minor (though possibly substantive) follow up points.
| } | ||
| const double dist(x - xGap); | ||
| if (std::abs(dist) < distToXGap) | ||
| distToXGap = dist; |
There was a problem hiding this comment.
Does this not risk signing a negative value to distToXGap, which would then fail all subsequent comparisons?
| const LArCaloHit *const pLArHit1(dynamic_cast<const LArCaloHit *>(pCaloHit1)); | ||
|
|
||
| if (!pLArHit1) | ||
| continue; |
There was a problem hiding this comment.
That was just a point of ordering. You check for LArCaloHit dynamic cast before you know if you're going to use this hit (if you don't, it's a redundant op and check).
AndyChappell
left a comment
There was a problem hiding this comment.
Latest changes look good. I won't tag it as approved yet because the SDK geometry updates, but in terms of the algorithm as presented, this one is ready.
Hello again,
This PR introduces the DLShowerMatching. The DLShowerMatching is called the DLMultiViewMatchingAlgorithm (it's not actually specific to showers). The algorithm works as follows:
These tools are:
Okay so, there is a spicy element to the PR - the LArCaloHit updates. I think we need to read in more information about the geometry into pandora. I 100% agree that this is not the best way to do it. Ideally we'd want to pass in a mapping between wires->overlapping wire range for each wire, in each plane, in each daughter volume. But I don't see how that's possible with the current SDK. I am very happy to discuss other approaches.