Filter to select events with the primary + pileup are above a threshold#1747
Filter to select events with the primary + pileup are above a threshold#1747michaelmackenzie wants to merge 4 commits intoMu2e:mainfrom
Conversation
|
Hi @michaelmackenzie,
which require these tests: build. @Mu2e/fnalbuild-users, @Mu2e/write have access to CI actions on main. ⌛ The following tests have been triggered for ab08083: build (Build queue - API unavailable) |
There was a problem hiding this comment.
Pull request overview
Adds a new ART filter module to preselect simulation events based on calorimeter energy deposition from the primary SimParticle plus nearby pileup, motivated by Run 1B studies to reduce downstream digi-making time.
Changes:
- Introduces
CaloPileupDtsFilterEDFilter that computes primary calorimeter Edep and adds nearby-in-time/space pileup Edep. - Applies configurable primary/total energy cuts and time/space proximity windows.
- Adds basic diagnostics and end-of-job pass/fail summary.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| bool CaloPileupDtsFilter::goodParticle(SimParticle const& simp) const { | ||
| // Check if the SimParticle is a valid particle to consider for pileup filtering | ||
| return true; // For now, accept all particles | ||
| } |
There was a problem hiding this comment.
goodParticle() currently ignores its argument and always returns true, which will typically trigger an unused-parameter warning under common warning flags. If it's intentionally a placeholder, consider omitting the parameter name or marking it [[maybe_unused]] until real selection logic is added.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| for(const auto& p : primary.primarySimParticles()) { | ||
| std::cout << " Primary particle: PDG = " << p->pdgId() | ||
| << " E = " << p->startMomentum().e() | ||
| << " t = " << p->startGlobalTime() | ||
| << std::endl; | ||
| } |
There was a problem hiding this comment.
The diagnostic loop dereferences p without checking isNull(). Since the later logic explicitly handles sim.isNull(), this printout can segfault when a null art::Ptr is present. Guard the print with if(p.isNull()) continue; (or print a placeholder) before using p->....
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| if(time_diff < timeWindow_ && space_diff < spaceWindow_) { | ||
| pileup_edep += css.energyDepBirks(); | ||
| if(diagLevel_ > 2) { |
There was a problem hiding this comment.
As soon as primary_edep + pileup_edep exceeds maxTotalEnergy_, the final selection can no longer pass, but the code continues scanning remaining steps. Consider early-exiting (or breaking out of loops) once the running total is already above maxTotalEnergy_ to reduce CPU for high-occupancy events.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
☔ The build tests failed for ab08083.
N.B. These results were obtained from a build of this Pull Request at ab08083 after being merged into the base branch at 191ad5d. For more information, please check the job page here. |
|
I'll review this pull request. Let me start by loading the relevant ability and fetching the PR details.Now let me also check the existing review comments on this PR:Here's my review of PR #1747 — a new // 327 lines added, 0 deletedIssues Found🔴 Bug — Time wrap-around not handled (High Severity)double time_diff = std::fabs(std::fmod(css.time(), mbtime) - primary_time);The Fix: Compute the wrapped circular distance: double t = std::fmod(css.time(), mbtime);
double time_diff = std::fabs(t - primary_time);
time_diff = std::min(time_diff, mbtime - time_diff);The same issue applies to the primary time averaging (line ~172), where 🔴 Bug — Potential null pointer dereference in diagnostic loop (High Severity) for(const auto& p : primary.primarySimParticles()) {
std::cout << " Primary particle: PDG = " << p->pdgId()
<< " E = " << p->startMomentum().e()
<< " t = " << p->startGlobalTime()
<< std::endl;
}The diagnostic loop dereferences Fix: Add 🟡 Missing includes —
|
| Severity | Issue | Status |
|---|---|---|
| 🔴 High | Time wrap-around bug in pileup matching | Needs fix |
| 🔴 High | Null ptr dereference in diagnostic print | Needs fix |
| 🟡 Medium | Missing <iostream>/<cmath> includes |
Fixed in later commits |
| 🟡 Low | Unused parameter warning in goodParticle() |
Needs fix |
| 🟡 Medium | No early-exit when total energy exceeds max | Optimization opportunity |
The time wrap-around bug is the most critical issue — it will silently produce incorrect filtering results for events with pileup near the microbunch boundary.
This is motivated by Run 1B studies, to select DIO primary events that either are high energy calo deposits on their own or through the addition of pileup. This is run before digi-making, which takes a significant amount of time and we therefore want to cut down on this time.