Skip to content

Commit fd16dea

Browse files
wdconincCopilot
andauthored
fix: use thread-local fastjet AreaDefinition to avoid contention (#2451)
### Briefly, what does this PR introduce? This PR fixes the ghosts in the jet machine. It was a bit surprising to see fastjet take up this much time in the janatop listing, but it starts to make sense when you read the headers. Also, @veprbl correctly identified that ghosts were the cause. By default, fastjet runs with a single static and locked random generator. The [header](https://gitlab.com/fastjet/fastjet/-/blob/master/include/fastjet/GhostedAreaSpec.hh?ref_type=heads) has some guildelines about how to specify a fixed seed for each event and run with a thread-local area definition. This implements that approach. Note: due to the changing seeds, this will change the jet collections, but they should still be statistically consistent, and they should be identical between ST and MT running. ### What kind of change does this PR introduce? - [x] Bug fix (issue: too much time spent in jet reconstruction, even accounting for combinatorics) - [ ] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? Yes, jet collections will be different but statistically consistent. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 98bbbd3 commit fd16dea

File tree

4 files changed

+33
-17
lines changed

4 files changed

+33
-17
lines changed

src/algorithms/reco/JetReconstruction.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ void JetReconstruction<InputT>::process(
103103
const typename JetReconstructionAlgorithm<InputT>::Input& input,
104104
const typename JetReconstructionAlgorithm<InputT>::Output& output) const {
105105
// Grab input collections
106-
const auto [input_collection] = input;
107-
auto [jet_collection] = output;
106+
const auto [headers, input_collection] = input;
107+
auto [jet_collection] = output;
108108

109109
// extract input momenta and collect into pseudojets
110110
std::vector<PseudoJet> particles;
@@ -130,9 +130,16 @@ void JetReconstruction<InputT>::process(
130130
}
131131
this->trace(" Number of particles: {}", particles.size());
132132

133+
// Create per-event AreaDefinition with reproducible seed
134+
// This avoids contention on fastjet's static random generator
135+
auto seed = m_uid.getUniqueID(*headers, this->name());
136+
std::vector<int> seed_vector = {static_cast<int>(seed & 0xFFFFFFFF),
137+
static_cast<int>((seed >> 32) & 0xFFFFFFFF)};
138+
auto local_area_def = m_area_def->with_fixed_seed(seed_vector);
139+
133140
// Run the clustering, extract the jets
134-
fastjet::ClusterSequenceArea m_clus_seq(particles, *m_jet_def, *m_area_def);
135-
std::vector<PseudoJet> jets = sorted_by_pt(m_clus_seq.inclusive_jets(m_cfg.minJetPt));
141+
fastjet::ClusterSequenceArea clus_seq(particles, *m_jet_def, local_area_def);
142+
std::vector<PseudoJet> jets = sorted_by_pt(clus_seq.inclusive_jets(m_cfg.minJetPt));
136143

137144
// Print out some infos
138145
this->trace(" Clustering with : {}", m_jet_def->description());

src/algorithms/reco/JetReconstruction.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <algorithms/algorithm.h>
77
#include <edm4eic/ReconstructedParticleCollection.h>
8+
#include <edm4hep/EventHeaderCollection.h>
89
#include <fastjet/AreaDefinition.hh>
910
#include <fastjet/JetDefinition.hh>
1011
#include <map>
@@ -16,13 +17,14 @@
1617
#include "JetReconstructionConfig.h"
1718
// for algorithm configuration
1819
#include "algorithms/interfaces/WithPodConfig.h"
20+
#include "algorithms/interfaces/UniqueIDGenSvc.h"
1921

2022
namespace eicrecon {
2123

2224
template <typename InputT>
23-
using JetReconstructionAlgorithm =
24-
algorithms::Algorithm<algorithms::Input<typename InputT::collection_type>,
25-
algorithms::Output<edm4eic::ReconstructedParticleCollection>>;
25+
using JetReconstructionAlgorithm = algorithms::Algorithm<
26+
algorithms::Input<edm4hep::EventHeaderCollection, typename InputT::collection_type>,
27+
algorithms::Output<edm4eic::ReconstructedParticleCollection>>;
2628

2729
template <typename InputT>
2830
class JetReconstruction : public JetReconstructionAlgorithm<InputT>,
@@ -32,7 +34,7 @@ class JetReconstruction : public JetReconstructionAlgorithm<InputT>,
3234
JetReconstruction(std::string_view name)
3335
: JetReconstructionAlgorithm<InputT>{
3436
name,
35-
{"inputReconstructedParticles"},
37+
{"eventHeaderCollection", "inputReconstructedParticles"},
3638
{"outputReconstructedParticles"},
3739
"Performs jet reconstruction using a FastJet algorithm."} {}
3840

@@ -86,6 +88,9 @@ class JetReconstruction : public JetReconstructionAlgorithm<InputT>,
8688
std::string areaType;
8789
} m_defaultFastjetOpts = {"antikt_algorithm", "E_scheme", "active_area"};
8890

91+
// unique ID service for generating reproducible seeds
92+
const algorithms::UniqueIDGenSvc& m_uid = algorithms::UniqueIDGenSvc::instance();
93+
8994
}; // end JetReconstruction definition
9095

9196
} // namespace eicrecon

src/factories/reco/JetReconstruction_factory.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class JetReconstruction_factory
2222
private:
2323
std::unique_ptr<Algo> m_algo;
2424

25-
// input collection
25+
// input collections
26+
typename FactoryT::template PodioInput<edm4hep::EventHeader> m_event_header_input{this};
2627
typename FactoryT::template PodioInput<InputT> m_input{this};
2728

2829
// output collection
@@ -59,7 +60,7 @@ class JetReconstruction_factory
5960
}
6061

6162
void Process(int32_t /* run_number */, uint64_t /* event_number */) {
62-
m_algo->process({m_input()}, {m_output().get()});
63+
m_algo->process({m_event_header_input(), m_input()}, {m_output().get()});
6364
}
6465

6566
}; // end JetReconstruction_factory definition

src/global/reco/reco.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,22 @@ void InitPlugin(JApplication* app) {
142142
app));
143143

144144
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
145-
"GeneratedJets", {"GeneratedParticles"}, {"GeneratedJets"}, {}, app));
145+
"GeneratedJets", {"EventHeader", "GeneratedParticles"}, {"GeneratedJets"}, {}, app));
146146

147147
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
148-
"ReconstructedJets", {"ReconstructedParticles"}, {"ReconstructedJets"}, {}, app));
148+
"ReconstructedJets", {"EventHeader", "ReconstructedParticles"}, {"ReconstructedJets"}, {},
149+
app));
149150

150151
app->Add(new JOmniFactoryGeneratorT<ChargedReconstructedParticleSelector_factory>(
151152
"GeneratedChargedParticles", {"GeneratedParticles"}, {"GeneratedChargedParticles"}, app));
152153

153154
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
154-
"GeneratedChargedJets", {"GeneratedChargedParticles"}, {"GeneratedChargedJets"}, {}, app));
155+
"GeneratedChargedJets", {"EventHeader", "GeneratedChargedParticles"},
156+
{"GeneratedChargedJets"}, {}, app));
155157

156158
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
157-
"ReconstructedChargedJets", {"ReconstructedChargedParticles"}, {"ReconstructedChargedJets"},
158-
{}, app));
159+
"ReconstructedChargedJets", {"EventHeader", "ReconstructedChargedParticles"},
160+
{"ReconstructedChargedJets"}, {}, app));
159161

160162
app->Add(new JOmniFactoryGeneratorT<ScatteredElectronsTruth_factory>(
161163
"ScatteredElectronsTruth",
@@ -247,11 +249,12 @@ void InitPlugin(JApplication* app) {
247249
{"GeneratedBreitFrameParticles"}, {}, app));
248250

249251
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
250-
"GeneratedCentauroJets", {"GeneratedBreitFrameParticles"}, {"GeneratedCentauroJets"},
252+
"GeneratedCentauroJets", {"EventHeader", "GeneratedBreitFrameParticles"},
253+
{"GeneratedCentauroJets"},
251254
{.rJet = 0.8, .jetAlgo = "plugin_algorithm", .jetContribAlgo = "Centauro"}, app));
252255

253256
app->Add(new JOmniFactoryGeneratorT<JetReconstruction_factory<edm4eic::ReconstructedParticle>>(
254-
"ReconstructedCentauroJets", {"ReconstructedBreitFrameParticles"},
257+
"ReconstructedCentauroJets", {"EventHeader", "ReconstructedBreitFrameParticles"},
255258
{"ReconstructedCentauroJets"},
256259
{.rJet = 0.8, .jetAlgo = "plugin_algorithm", .jetContribAlgo = "Centauro"}, app));
257260

0 commit comments

Comments
 (0)