Skip to content

Allow cz restriction with CE generation#1782

Merged
oksuzian merged 3 commits intoMu2e:mainfrom
michaelmackenzie:CzRestriction
Apr 6, 2026
Merged

Allow cz restriction with CE generation#1782
oksuzian merged 3 commits intoMu2e:mainfrom
michaelmackenzie:CzRestriction

Conversation

@michaelmackenzie
Copy link
Copy Markdown
Contributor

Allow cos(theta_z) restriction in Ce endpoint random unit sphere

@FNALbuild
Copy link
Copy Markdown
Collaborator

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

  • EventGenerator

which require these tests: build.

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

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

About FNALbuild. Code review on Mu2e/Offline.

@FNALbuild
Copy link
Copy Markdown
Collaborator

☀️ The build tests passed at c54976b.

Test Result Details
test with Command did not list any other PRs to include
merge Merged c54976b at a31b07e
build (prof) Log file. Build time: 04 min 07 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 5 warnings
whitespace check no whitespace errors found

N.B. These results were obtained from a build of this Pull Request at c54976b after being merged into the base branch at a31b07e.

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.

@oksuzian
Copy link
Copy Markdown
Collaborator

oksuzian commented Apr 6, 2026

I'll review this pull request by examining the changes and details.Now let me look at the RandomUnitSphere class to understand its constructor and how czMin/czMax are handled:Here's my review of PR #1782. The change is small (1 file, +3/−1 lines) and the core idea — exposing czMin/czMax fhicl parameters and forwarding them to RandomUnitSphere — is straightforward and correct. However, I found several issues worth addressing:


1. 🔴 No input validation on czMin / czMax

There is no check that the user-provided values are physically sensible. Invalid configurations will silently produce wrong results (or no results at all if czMin > czMax).

Suggested fix — add validation in the constructor body (around line 90):

    , randomUnitSphere_{eng_, conf().czMin(), conf().czMax()}
    , pdgId_(conf().pdgId())

Add after line 90 inside the constructor body:

    if(conf().czMin() < -1. || conf().czMax() > 1. || conf().czMin() >= conf().czMax()) {
      throw cet::exception("BADINPUT")
        << "CeEndpoint: invalid czMin/czMax range ["
        << conf().czMin() << ", " << conf().czMax() << "]. "
        << "Require -1 <= czMin < czMax <= 1.\n";
    }

2. 🟡 Missing normalization / weight correction for restricted cos(θ_z) range

When czMin/czMax restrict the angular acceptance to less than the full sphere, the generated events no longer represent the full phase space. If downstream code assumes isotropic generation (e.g., for Rmue normalization, which the comment on line 131 says is "per muon"), the effective solid-angle fraction should either be:

  • documented clearly so users know they must account for it, or
  • applied as a weight/correction factor.

This isn't necessarily a code bug, but it's a physics concern. Consider adding a comment or log message stating the solid-angle fraction being generated:

    if(conf().czMin() > -1. || conf().czMax() < 1.) {
      double fraction = (conf().czMax() - conf().czMin()) / 2.0;
      mf::LogInfo("CeEndpoint") << "Restricting cos(theta_z) to ["
        << conf().czMin() << ", " << conf().czMax()
        << "], solid angle fraction = " << fraction << "\n";
    }

3. 🟡 Verbosity log doesn't report the new cz parameters

The existing verbose log block (lines 107–113) reports stoppingTargetMaterial, endpoint energy, and muon lifetime, but does not log the new czMin/czMax values. This makes debugging harder when a non-default range is used.

    if(verbosity_ > 0) {
      mf::LogInfo log("CeEndpoint");
      log<<"stoppingTargetMaterial = "<<conf().stoppingTargetMaterial()
         <<", endpoint energy = "<<endPointEnergy_
         <<", muon lifetime = "<<muonLifeTime_
+        <<", czMin = "<<conf().czMin()
+        <<", czMax = "<<conf().czMax()
         <<std::endl;
    }

4. 🟢 Minor: fhicl parameter naming convention

The existing parameters use camelCase (inputSimParticles, stoppingTargetMaterial), which is consistent with the new czMin/czMax. This looks fine — just noting it passes convention review.


Summary

# Severity Issue
1 🔴 High No validation on czMin/czMax — invalid ranges silently produce wrong physics
2 🟡 Medium No documentation or warning about solid-angle normalization impact
3 🟡 Medium New parameters not included in verbose logging
4 🟢 Info Naming convention is consistent ✅

The code change itself is mechanically correct — the RandomUnitSphere constructor does accept the czmin/czmax arguments in exactly this form. The main concern is the lack of input guardrails and logging for the new parameters.

@michaelmackenzie
Copy link
Copy Markdown
Contributor Author

I added an error throw for bad cz range values and added the values to the logged output

@oksuzian
Copy link
Copy Markdown
Collaborator

oksuzian commented Apr 6, 2026

@FNALbuild build test

@oksuzian
Copy link
Copy Markdown
Collaborator

oksuzian commented Apr 6, 2026

@FNALbuild run build test

@FNALbuild
Copy link
Copy Markdown
Collaborator

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

Copy link
Copy Markdown
Collaborator

@brownd1978 brownd1978 left a comment

Choose a reason for hiding this comment

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

Would it make sense to record the acceptance of the cz cut ( 0.5*(czmax-czmin)) as a FilterFraction in the enjob? That would allow computing the net POT equivalent without having to harvest numbers from a log file.

@michaelmackenzie
Copy link
Copy Markdown
Contributor Author

@brownd1978 I was thinking about this as well, either as an EventWeight (but being per-event is wasteful) or a FilterFraction (but it's not really filtering gen events). I could make a new data product SubRunWeight to cover this? Or just put EventWeight into the sub run. I don't think the FilterFraction payload/accumulation will make as much sense here, but I haven't thought about it too deeply

@FNALbuild
Copy link
Copy Markdown
Collaborator

📝 The HEAD of main has changed to 50ac9dc. Tests are now out of date.

@FNALbuild
Copy link
Copy Markdown
Collaborator

☔ The build is failing at 6c62b85.

scons: *** [build/al9-prof-e29-p092/Offline/tmp/EventGenerator/src/CeEndpoint_module.os] Error 1
Test Result Details
test with Command did not list any other PRs to include
merge Merged 6c62b85 at a31b07e
build (prof) Log file.
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 6 warnings
whitespace check no whitespace errors found

N.B. These results were obtained from a build of this Pull Request at 6c62b85 after being merged into the base branch at a31b07e.

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.

@michaelmackenzie
Copy link
Copy Markdown
Contributor Author

@FNALbuild run build test

@FNALbuild
Copy link
Copy Markdown
Collaborator

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

@FNALbuild
Copy link
Copy Markdown
Collaborator

☀️ The build tests passed at 713ba67.

Test Result Details
test with Command did not list any other PRs to include
merge Merged 713ba67 at 50ac9dc
build (prof) Log file. Build time: 08 min 24 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 5 warnings
whitespace check no whitespace errors found

N.B. These results were obtained from a build of this Pull Request at 713ba67 after being merged into the base branch at 50ac9dc.

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.

@oksuzian oksuzian merged commit c6b091b into Mu2e:main Apr 6, 2026
14 checks passed
@michaelmackenzie michaelmackenzie deleted the CzRestriction branch April 6, 2026 17:49
@brownd1978
Copy link
Copy Markdown
Collaborator

brownd1978 commented Apr 6, 2026 via email

@michaelmackenzie
Copy link
Copy Markdown
Contributor Author

@brownd1978 What would you suggest for nseen_ and npassed_ for the object? As these are integers, setting the weight becomes a bit tricky in that we'd need to represent the double correction value as a fraction. It also has payloads bool chained_, uint64_t nseen_ , and uint64_t npassed_ instead of essentially the double fraction_ we'd ideally store here.

Perhaps more appropriate would be SpectrumConfig struct that could have emin_, emax_, tmin_, tmax_, czmin_, czmax_, and fraction_sampled_ for commonly configured generation values. This would also help flat electron/photon datasets that need (emax - emin) for proper normalization. Of course it wouldn't cover all cases, but this could consolidate some of these issues into a single solution struct.

@brownd1978
Copy link
Copy Markdown
Collaborator

brownd1978 commented Apr 6, 2026 via email

@michaelmackenzie
Copy link
Copy Markdown
Contributor Author

There isn't a SpectrumConfig struct, I meant this as a proposal. I'm often annoyed that I have to check fcl to know emin/emax or czmin/czmax, where something like this would automate this. But I don't feel strongly, just adding this as an idea to target two issues at once

@brownd1978
Copy link
Copy Markdown
Collaborator

brownd1978 commented Apr 6, 2026 via email

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.

4 participants