Skip to content

Commit 8f9c836

Browse files
zhaozhiwenclaude
andcommitted
Normalize run weights before stochastic event distribution
distributeEvents drew randomNumber from U[0,1] and compared it to a running sum of the raw file weights. The weights are relative and not required to sum to 1, so for a file like "11 1 / 12 7 / 13 2" (cumulative bins 1/8/10) every draw is <= 1 and the first run always wins — runs 12 and 13 get zero events, with no warning. The code only worked when the weights happened to sum to 1. Compute the total weight once and scale each draw by it (and guard a non-positive total). Scaling the draw rather than mutating runWeights keeps the logged weight table showing the user's original values. Verified: a 1/7/2 weights file over 1000 events now distributes 97/697/206 (~10/70/20%); before, all 1000 went to the first run (Geant4 11.4.1 dev container). Fixes #103 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 48f83e5 commit 8f9c836

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

gemc/eventDispenser/eventDispenser.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,19 @@ void EventDispenser::distributeEvents(int nevents_to_process) {
104104
mt19937 generator(randomDevice());
105105
uniform_real_distribution<> randomDistribution(0, 1);
106106

107+
// Weights in the run-weights file are relative, not required to sum to 1. Compute the total
108+
// once and scale each draw by it, so non-normalized weights distribute events correctly.
109+
double totalWeight = 0;
110+
for (const auto& weight : runWeights) { totalWeight += weight.second; }
111+
if (totalWeight <= 0) {
112+
log->error(ERR_EVENTDISTRIBUTIONFILENOTFOUND,
113+
"Run weights sum to ", totalWeight, " (must be > 0). Check your run weights file.");
114+
return;
115+
}
116+
107117
// For each event, select a run by comparing a random draw to the cumulative weight intervals.
108-
// This assumes runWeights values represent fractions or relative weights normalized to sum to 1.
109118
for (int i = 0; i < nevents_to_process; i++) {
110-
double randomNumber = randomDistribution(generator);
119+
double randomNumber = randomDistribution(generator) * totalWeight;
111120

112121
double cumulativeWeight = 0;
113122
for (const auto& weight : runWeights) {

0 commit comments

Comments
 (0)