Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 17, 2025

Problem

The MatchClusters algorithm was not reconstructing photons even when clusters were present. The issue was in the cluster matching logic where photon clusters were incorrectly consumed by charged particle tracks during Step 1 (charged particle matching), preventing them from being reconstructed as neutral particles in Step 2.

Root Cause

In src/algorithms/reco/MatchClusters.cc (lines 67-73), the algorithm matched clusters to tracks purely by mcID without checking if the associated MC particle was actually charged. This caused photon clusters to be incorrectly matched to charged particle tracks when they shared the same mcID, removing them from the clusterMap and preventing proper neutral particle reconstruction.

Solution

Added a charge check before matching clusters to tracks. The algorithm now:

  1. Retrieves the MC particle associated with the mcID
  2. Checks if the MC particle's charge is non-zero (getCharge() != 0.0F)
  3. Only matches and removes the cluster from clusterMap if the MC particle is actually charged
  4. Logs a debug message when skipping neutral particle clusters
if (clusterMap.contains(mcID)) {
  const auto& mc_particle = (*mcparticles)[mcID];
  
  // Only match cluster if the MC particle is actually charged
  if (mc_particle.getCharge() != 0.0F) {
    const auto& clus = clusterMap[mcID];
    debug("    --> found matching cluster with energy: {}", clus.getEnergy());
    debug("    --> adding cluster to reconstructed particle");
    outpart.addToClusters(clus);
    clusterMap.erase(mcID);
  } else {
    debug("    --> mcID {} corresponds to neutral particle (PDG: {}), skipping cluster match",
          mcID, mc_particle.getPDG());
  }
}

Impact

After this fix:

  • Photon clusters remain in the clusterMap during Step 1 and are properly reconstructed as neutral particles in Step 2
  • The algorithm correctly distinguishes between charged and neutral particle clusters based on MC truth information
  • Photons and other neutral particles are now properly reconstructed

Testing

The change is minimal (13 lines added, 5 lines modified) and follows existing code patterns in the same file (line 99 uses the same getCharge() check). The fix ensures that only truly charged particles consume clusters during track matching, allowing neutral particle clusters to pass through to the neutral reconstruction step.

Original prompt

Problem

The MatchClusters algorithm is not reconstructing photons even when there are clusters present. The issue is in the cluster matching logic where clusters can be incorrectly consumed by charged particle tracks.

Root Cause

In src/algorithms/reco/MatchClusters.cc, the algorithm matches clusters to tracks purely by mcID without checking if the associated MC particle is actually charged (lines 67-73). This causes photon clusters to be incorrectly matched to charged particle tracks if they share the same mcID, preventing them from being reconstructed as neutral particles in Step 2.

Solution

Add a charge check before matching clusters to tracks. Only match and remove clusters from the clusterMap if the associated MC particle is actually charged (getCharge() != 0.0F).

Changes Required

In src/algorithms/reco/MatchClusters.cc, modify the cluster matching section (around lines 67-73) to:

  1. Retrieve the MC particle associated with the mcID
  2. Check if the MC particle's charge is non-zero
  3. Only match the cluster and remove it from clusterMap if the MC particle is charged
  4. Add a debug message when skipping neutral particle clusters

The modified logic should look like:

if (clusterMap.contains(mcID)) {
  const auto& mc_particle = (*mcparticles)[mcID];
  
  // Only match cluster if the MC particle is actually charged
  if (mc_particle.getCharge() != 0.0F) {
    const auto& clus = clusterMap[mcID];
    debug("    --> found matching cluster with energy: {}", clus.getEnergy());
    debug("    --> adding cluster to reconstructed particle");
    outpart.addToClusters(clus);
    clusterMap.erase(mcID);
  } else {
    debug("    --> mcID {} corresponds to neutral particle (PDG: {}), skipping cluster match",
          mcID, mc_particle.getPDG());
  }
}

This ensures that photon clusters remain in the clusterMap and get properly reconstructed as neutral particles in Step 2 of the algorithm.

Expected Outcome

After this fix:

  • Photon clusters will no longer be incorrectly consumed by charged particle tracks
  • Photons will be properly reconstructed as neutral particles
  • The algorithm will correctly distinguish between charged and neutral particle clusters based on MC truth information

This pull request was created as a result of the following prompt from Copilot chat.

Problem

The MatchClusters algorithm is not reconstructing photons even when there are clusters present. The issue is in the cluster matching logic where clusters can be incorrectly consumed by charged particle tracks.

Root Cause

In src/algorithms/reco/MatchClusters.cc, the algorithm matches clusters to tracks purely by mcID without checking if the associated MC particle is actually charged (lines 67-73). This causes photon clusters to be incorrectly matched to charged particle tracks if they share the same mcID, preventing them from being reconstructed as neutral particles in Step 2.

Solution

Add a charge check before matching clusters to tracks. Only match and remove clusters from the clusterMap if the associated MC particle is actually charged (getCharge() != 0.0F).

Changes Required

In src/algorithms/reco/MatchClusters.cc, modify the cluster matching section (around lines 67-73) to:

  1. Retrieve the MC particle associated with the mcID
  2. Check if the MC particle's charge is non-zero
  3. Only match the cluster and remove it from clusterMap if the MC particle is charged
  4. Add a debug message when skipping neutral particle clusters

The modified logic should look like:

if (clusterMap.contains(mcID)) {
  const auto& mc_particle = (*mcparticles)[mcID];
  
  // Only match cluster if the MC particle is actually charged
  if (mc_particle.getCharge() != 0.0F) {
    const auto& clus = clusterMap[mcID];
    debug("    --> found matching cluster with energy: {}", clus.getEnergy());
    debug("    --> adding cluster to reconstructed particle");
    outpart.addToClusters(clus);
    clusterMap.erase(mcID);
  } else {
    debug("    --> mcID {} corresponds to neutral particle (PDG: {}), skipping cluster match",
          mcID, mc_particle.getPDG());
  }
}

This ensures that photon clusters remain in the clusterMap and get properly reconstructed as neutral particles in Step 2 of the algorithm.

Expected Outcome

After this fix:

  • Photon clusters will no longer be incorrectly consumed by charged particle tracks
  • Photons will be properly reconstructed as neutral particles
  • The algorithm will correctly distinguish between charged and neutral particle clusters based on MC truth information

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI self-assigned this Oct 17, 2025
@wdconinc
Copy link
Contributor

@qunib Can you test this branch?

- Retrieve MC particle associated with mcID
- Only match and remove cluster if MC particle is charged (getCharge() != 0.0F)
- Add debug message when skipping neutral particle clusters
- Ensures photon clusters remain in clusterMap for proper reconstruction as neutrals in Step 2

Co-authored-by: wdconinc <[email protected]>
Copilot AI changed the title [WIP] Fix cluster matching logic for photon reconstruction Fix photon cluster matching by adding charge check in MatchClusters algorithm Oct 17, 2025
Copilot AI requested a review from wdconinc October 17, 2025 16:43
Copilot finished work on behalf of wdconinc October 17, 2025 16:43
@wdconinc wdconinc added the pre-commit.ci autofix Enable pre-commit.ci autofixes even for bot accounts label Oct 17, 2025
@pre-commit-ci pre-commit-ci bot removed the pre-commit.ci autofix Enable pre-commit.ci autofixes even for bot accounts label Oct 17, 2025
@wdconinc wdconinc marked this pull request as ready for review October 17, 2025 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants