Skip to content

Fix integer truncation in cosmic livetime resampling scale factor - #1940

Merged
oksuzian merged 1 commit into
Mu2e:mainfrom
oksuzian:fix-cosmic-livetime-scaling
Aug 25, 2026
Merged

Fix integer truncation in cosmic livetime resampling scale factor#1940
oksuzian merged 1 commit into
Mu2e:mainfrom
oksuzian:fix-cosmic-livetime-scaling

Conversation

@oksuzian

Copy link
Copy Markdown
Collaborator

Problem

Mu2eProductMixer::endSubRun computes the cosmic livetime scale factor with integer division:

float scaling = resampledEvents_ / generatedEvents_;

resampledEvents_ and generatedEvents_ are both unsigned int, so the ratio is truncated to its floor before the float assignment. The resampled CosmicLivetime product (instance mixed, the only livetime product S2Resampler.fcl keeps) is scaled by that floored value.

Consequences, measured against sim.mu2e.CosmicDSStopsCRYAll.MDC2025ab (GenEventCount = 128,783/subrun, S1 livetime 29.586 s/subrun):

dataset events/job true scaling stored livetime/subrun stored (true)
dts.mu2e.CosmicCRYAll.Run1Ban 100,000 0.776 0 0 s (22.97 s)
dts.mu2e.CosmicCRYAll.MDC2025ap 500,000 3.882 3 88.76 s (114.9 s, −23%)

Any S2 cosmic resampling with events/job below the mixin subrun's generated count stores exactly zero livetime; above it, livetime is understated by up to 1/floor(ratio). Present since c30db7e (2021).

Fix

Cast before dividing:

float scaling = static_cast<float>(resampledEvents_) / static_cast<float>(generatedEvents_);

One line; no interface change. Existing datasets can be corrected offline since the true scaling is recomputable from events/job and the S1 subrun GenEventCount.

🤖 Generated with Claude Code

resampledEvents_ / generatedEvents_ are both unsigned int, so the
division truncates to floor before the float assignment. Any cosmic
S2 resampling job with fewer resampled events than the mixin subrun's
generated count (128,783/subrun for CosmicDSStopsCRYAll.MDC2025ab)
stores CosmicLivetime = 0; otherwise the livetime is understated by
up to 1/floor(ratio) (e.g. -23% for dts.mu2e.CosmicCRYAll.MDC2025ap,
scaling 3.88 stored as 3).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@FNALbuild

Copy link
Copy Markdown
Collaborator

Hi @oksuzian,
You have proposed changes to files in these packages:

  • EventMixing

which require these tests: build.

@Mu2e/write, @Mu2e/fnalbuild-users have access to CI actions on main.

⌛ The following tests have been triggered for 52ff4a0: build (Build queue - API unavailable)

About FNALbuild. Code review on Mu2e/Offline.

@FNALbuild

Copy link
Copy Markdown
Collaborator

☀️ The build tests passed at 52ff4a0.

Test Result Details
test with Command did not list any other PRs to include
merge Merged 52ff4a0 at 8ca6473
build (prof) Log file. Build time: 04 min 21 sec
ceSimReco Log file.
g4test_03MT Log file.
transportOnly Log file.
POT Log file.
g4study Log file.
cosmicSimReco Log file.
cosmicOffSpill Log file.
ceSteps Log file.
ceDigi Log file.
muDauSteps Log file.
ceMix Log file.
rootOverlaps Log file.
g4surfaceCheck Log file.
trigger Log file.
check_cmake Log file.
FIXME, TODO TODO (0) FIXME (0) in 1 files
clang-tidy ➡️ 2 errors 14 warnings
whitespace check no whitespace errors found

N.B. These results were obtained from a build of this Pull Request at 52ff4a0 after being merged into the base branch at 8ca6473.

For more information, please check the job page here.
Build artifacts are deleted after 5 days. If this is not desired, select Keep this build forever on the job page.

@rlcee rlcee left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you check for other instances of this issue in this module?

@oksuzian
oksuzian marked this pull request as ready for review August 24, 2026 16:44
@oksuzian

Copy link
Copy Markdown
Collaborator Author

Yes — I swept the module. This is the only integer division in EventMixing: the only other / operators are in ProtonBunchIntensityLogNormal_module.cc and are all double-precision math.

I also checked the adjacent line: in totalPrimaries_ * scaling the product is a float, but the CosmicLivetime constructor's first argument is unsigned long long, so the primaries field is truncated to an integer. For CRY that field is a dummy (the generator stores primaries=1 and the CRY-internal livetime), and for CORSIKA the loss is under one primary out of the full count, so no change is needed there — the livetime itself flows through as float.

For scale of the original problem: with resampledEvents < generatedEvents the stored livetime is exactly 0 (e.g. dts.mu2e.CosmicCRYAll.Run1Ban, 100k resampled from ~129k available per subrun), and otherwise it is floored (dts.mu2e.CosmicCRYAll.MDC2025ap: scaling 3.88 stored as 3, livetime -23%; MDC2020ar: 11.82 stored as 11, -6.9%). Existing datasets can be corrected offline since the true ratio is recomputable from the dts and stage-1 gencounts.

@oksuzian
oksuzian merged commit 3f6e789 into Mu2e:main Aug 25, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants