Skip to content

MModuleEventFilter: strip hit energies of both sides are summed, empty events skip the energy filter, the detector list is never used, the default maximum reduced chi square does not survive the XML round trip #262

Open

Description

@zoglauer

This issue was written by Claude under the direction of @zoglauer.

The unit test UTNModuleEventFilter (PR #247) marks all problems below as known failures with ExpectedToFail() (5 checks). All links refer to src/MModuleEventFilter.cxx unless noted.

1. Strip hit energies of both detector sides are summed

} else if (Event->GetNStripHits() > 0) {
double Total = 0;
for (unsigned int h = 0; h < Event->GetNStripHits(); ++h) {
Total += Event->GetStripHit(h)->GetEnergy();
}
if (Total < m_MinimumTotalEnergy || Total > m_MaximumTotalEnergy) {
FilteredOut = true;
}
}

If an event has no hits yet (e.g. the filter runs before strip pairing), the total energy is the sum of all strip hits, LV and HV. Every interaction is seen on both sides, so its energy is counted twice: a 511 keV interaction gives 1022 keV, and the energy window filters the wrong events.

Suggested fix: use the energy of one side only (e.g. the LV strips), or the larger of the two side sums.

2. Events without any hit skip the energy filter

if (Event->GetPhysicalEvent() != 0) {
MPhysicalEvent* E = Event->GetPhysicalEvent();
if (E->Ei() < m_MinimumTotalEnergy || E->Ei() > m_MaximumTotalEnergy) {
FilteredOut = true;
}
} else if (Event->GetNHits() > 0) {
double Total = 0;
for (unsigned int h = 0; h < Event->GetNHits(); ++h) {
Total += Event->GetHit(h)->GetEnergy();
}
if (Total < m_MinimumTotalEnergy || Total > m_MaximumTotalEnergy) {
FilteredOut = true;
}
} else if (Event->GetNStripHits() > 0) {
double Total = 0;
for (unsigned int h = 0; h < Event->GetNStripHits(); ++h) {
Total += Event->GetStripHit(h)->GetEnergy();
}
if (Total < m_MinimumTotalEnergy || Total > m_MaximumTotalEnergy) {
FilteredOut = true;
}
}

The energy filter is an if / else if chain over physical event, hits and strip hits. An event with none of them takes no branch and is never checked against the minimum energy, so an empty event (energy 0) passes a filter with e.g. a 400 keV minimum.

Suggested fix: treat an event without any energy as total energy 0 and apply the energy window.

3. The detector list is never used

SetDetectorList() / GetDetectorList() store a list of detector IDs (header L68-L70), but AnalyzeEvent() does not filter by it, and the list is neither written to nor read from the XML configuration (L218-L300). Nothing in nuclearizer calls the setter.

To do: either implement the detector selection (filter, XML, GUI), or remove the unused list and the related checks from the unit test.

4. Minor: the default maximum reduced chi square becomes infinity after the XML round trip

The default of m_MaximumStripPairingReducedChiSquare is numeric_limits<double>::max() (L95). Written to XML with limited precision, it is read back as a value larger than the maximum, i.e. infinity (L262-L265). The filter still behaves the same, but the configuration does not round-trip.

To do: use a finite default, or accept infinity, document it, and remove the related check from the unit test.

Done when: all problems described in this issue are fixed, all ExpectedToFail() instances related to this issue are removed from the unit tests, and the unit tests pass on both macOS and Linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions