ldmx-sw icon indicating copy to clipboard operation
ldmx-sw copied to clipboard

Use central Random Number Seed Service rather than config

Open tomeichlersmith opened this issue 1 year ago • 7 comments

https://github.com/LDMX-Software/ldmx-sw/blob/4e76f4267d6986cbdef9ecdcf76efe7d5330b2a9/TrigScint/src/TrigScint/TrigScintDigiProducer.cxx#L29-L30

:cry:

#1385 reminded me of this since we need to set the randomSeed for the TS digi processors within the CI.

https://github.com/LDMX-Software/ldmx-sw/blob/4e76f4267d6986cbdef9ecdcf76efe7d5330b2a9/Ecal/src/Ecal/EcalDigiProducer.cxx#L73-L78

The seeding in ECal is done in produce because it was written before a patch to Framework allowing use of conditions within onNewRun. I would suggest putting the same code within onNewRun to avoid confusion of future developers and to avoid unnecessary checks. Moving the seeding to onNewRun cleans up the code and makes it obvious that the RNG does not need to be seeded on every event. This also gives us the opportunity to switch to using STL like Tracking instead of TRandom.

Solution

One can seed their noise generator within onNewRun which is the first callback that happens after the conditions are configured. This gives you access to the RNSS and allows you to have your seeds be produced via the central service which will change the seeds whenever all of the other seeds should change.

Examples https://github.com/LDMX-Software/ldmx-sw/blob/4e76f4267d6986cbdef9ecdcf76efe7d5330b2a9/Tracking/src/Tracking/Reco/DigitizationProcessor.cxx#L71-L75

where generator_ is a std::default_random_engine which can be passed to an instance of a distribution (for example std::normal_distribution<float>) to sample it.

tomeichlersmith avatar Aug 13 '24 11:08 tomeichlersmith

This is the same development as I did in https://github.com/LDMX-Software/ldmx-sw/pull/1359/commits/bda6d5c7145d052d7bac36cfc0eb3f8ea2640192 right? If yes, seems easy, I could put this on my todo list.

tvami avatar Aug 13 '24 14:08 tvami

Kinda. If you choose to use STL[^1], then you'll need to change TRandom to an equivalent STL distribution (std::uniform_int_distribution I believe) or you could follow whats in ECal for the ROOT way which just waits to create TRandom until access to the RNSS is available.

[^1]: I would prefer to use STL, but I want to be clear that it would incur slightly more development to drop TRandom completely.

tomeichlersmith avatar Aug 13 '24 14:08 tomeichlersmith

STL Implementation Ramble

The reason I like how STL implements this is because it separated the RNG from the distribution. This way, we can construct and configure a distribution within the constructor and/or configure methods and then seed the RNG somewhere else (like onNewRun). For example

void MyProc:configure(framework::config::Parameters& p) {
  my_distribution_ = std::make_unique<std::uniform_int_distribution>(0, p.getParameter<int>("max_rand_int"));
}

void MyProc::onNewRun(const ldmx::RunHeader& rh) {
 const auto& rnss{getCondition<...>(...)};
  rng_.seed(rnss.getSeed("MyProc::RNG"));
}

void MyProc::produce(Event& event) {
  int rand_id = (*my_distribution)(rng_);
}

The call site to get rand_id is ugly because we have to delay constructing my_distribution_ until configure. If you are able to construct my_distribution_ before run-time configuration, then you can avoid the std::unique_ptr wrapper and make it cleaner.

// dropping rest of construction boilerplate
MyProc::MyProc(...) : my_distribution_{0, 10} {}

// onNewRun is the same

void MyProc::produce(Event& event) {
  int rand_id = my_distribution_(rng_);
}

tomeichlersmith avatar Aug 13 '24 14:08 tomeichlersmith

Maybe we should have another issue that's regarding moving ECAL to STL as well, I understand the implementation choice for ecal was somewhat historical.

tvami avatar Aug 13 '24 15:08 tvami

That's a fair point, I'm also willing have this issue represent both since the implementations are so similar.

tomeichlersmith avatar Aug 13 '24 15:08 tomeichlersmith

, I'm also willing have this issue represent both

Sure let's do that

tvami avatar Aug 13 '24 15:08 tvami

I also propose to do this after the we have a new release with new golds

tvami avatar Aug 13 '24 16:08 tvami

While @tomeichlersmith moved the simple HCAL reco to this new approach, the "old" one still uses the TRandom https://github.com/LDMX-Software/ldmx-sw/blob/trunk/Hcal/src/Hcal/HcalDigiProducer.cxx#L57-L86

Anyway, part 1) with ECAL is done here https://github.com/LDMX-Software/ldmx-sw/pull/1605

tvami avatar Feb 13 '25 23:02 tvami

Part 2) https://github.com/LDMX-Software/ldmx-sw/pull/1614

tvami avatar Feb 16 '25 02:02 tvami

Part 3) is https://github.com/LDMX-Software/ldmx-sw/pull/1615

tvami avatar Feb 16 '25 03:02 tvami

I think this is done with the three parts @tvami did :)

tomeichlersmith avatar Feb 20 '25 20:02 tomeichlersmith