feat: Composable vertex position generators with event number#5308
Draft
paulgessinger wants to merge 8 commits intoacts-project:mainfrom
Draft
feat: Composable vertex position generators with event number#5308paulgessinger wants to merge 8 commits intoacts-project:mainfrom
paulgessinger wants to merge 8 commits intoacts-project:mainfrom
Conversation
…port Extend PrimaryVertexPositionGenerator interface to receive the event number, enabling generators that vary their output over time. Add two new generators: - AdditiveVertexPositionGenerator: composes multiple generators by summing their outputs, allowing layered vertex smearing strategies. - LumiBlockVertexPositionGenerator: produces a beamspot offset that is constant within a configurable luminosity block and changes between blocks using a deterministic PRNG seeded by block number. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…xGenerator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bind PrimaryVertexPositionGenerator.__call__ to Python so generators can be invoked directly in tests. Add tests that verify: - FixedVertexGenerator returns the configured position - GaussianVertexGenerator produces varying positions - AdditiveVertexGenerator sums constituent outputs correctly - LumiBlockVertexGenerator is consistent within a block and varies across blocks - Composed Gaussian + LumiBlock generator behaves correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
andiwand
reviewed
Apr 1, 2026
| std::size_t eventNumber) const override { | ||
| std::size_t block = eventNumber / blockSize; | ||
| // Deterministic per block: same block always gives the same offset. | ||
| std::mt19937 blockRng(block); |
Contributor
There was a problem hiding this comment.
even simpler than I imagined it first. should we allow to inject a seed here / actually inject the user provided seed somehow?
or get a random number from the central RNG+seed and use it as a seed here overall
Member
Author
There was a problem hiding this comment.
Yeah that's probably a good call. We just need to make sure it generates the exact same offset inside the block. Ideally the global seed that is passed in via the RNG instance should be respected.
Wraps another vertex generator and applies a deterministic per-lumi-block rotation (beam tilt) to its spatial output. The tilt angles around x and y are drawn from Gaussians seeded by a salted block number, so they are uncorrelated with LumiBlockVertexPositionGenerator when using the same block size. Includes Python bindings and tests verifying per-block consistency, length preservation, seed decorrelation, and full composition with Gaussian + tilt + positional shift. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Missed call site that also invokes the vertex generator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Replace the RandomEngine typedef (std::mt19937) with a thin wrapper class that stores the seed it was constructed with. This lets lumi-block vertex generators derive deterministic, user-seed-dependent per-block RNG seeds via boost::hash_combine(rng.seed(), blockNumber). The wrapper satisfies UniformRandomBitGenerator so all existing code (distributions, templates, function signatures) works unchanged. Update LumiBlockVertexPositionGenerator and LumiBlockRotationVertexPositionGenerator to incorporate rng.seed() into their per-block seeds, ensuring different user seeds produce different beamspot trajectories. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add combinedWith(extra) method to RandomEngine that returns a new engine whose seed is hash_combine(this->seed(), extra). This encapsulates the seed derivation pattern in one place. Simplify lumi-block generators to use rng.combinedWith(block) instead of manual boost::hash_combine calls. The rotation generator chains rng.combinedWith(block).combinedWith(salt) for decorrelation. Move boost/functional/hash.hpp include from VertexGenerators.hpp into RandomNumbers.hpp where the hash logic now lives. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove redundant m_engine() from RandomEngine default constructor initializer list - Use CTAD for std::normal_distribution in LumiBlockVertexPositionGenerator and LumiBlockRotationVertexPositionGenerator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
PrimaryVertexPositionGeneratorinterface to receive the event number, enabling vertex generators that vary their output over timeAdditiveVertexPositionGeneratorthat composes multiple generators by summing their outputsLumiBlockVertexPositionGeneratorthat produces a beamspot offset constant within a configurable luminosity block, changing between blocks via a deterministic PRNG seeded by block numberExample usage (Python)
Test plan
AdditiveVertexGeneratorcomposition in PythonLumiBlockVertexGeneratorproduces consistent offsets within a block and different offsets across blocks🤖 Generated with Claude Code