ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EventGenerator.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EventGenerator.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 #include <algorithm>
12 #include <cstdint>
13 #include <stdexcept>
14 
16 
18  : m_cfg(cfg), m_logger(Acts::getDefaultLogger("EventGenerator", lvl)) {
19  if (m_cfg.output.empty()) {
20  throw std::invalid_argument("Missing output collection");
21  }
22  if (m_cfg.generators.empty()) {
23  throw std::invalid_argument("No generators are configured");
24  }
25  if (!m_cfg.randomNumbers) {
26  throw std::invalid_argument("Missing random numbers service");
27  }
28 }
29 
30 std::string FW::EventGenerator::name() const {
31  return "EventGenerator";
32 }
33 
34 std::pair<size_t, size_t> FW::EventGenerator::availableEvents() const {
35  return {0u, SIZE_MAX};
36 }
37 
39  std::vector<SimVertex> event;
40 
41  auto rng = m_cfg.randomNumbers->spawnGenerator(ctx);
42  // number of primary vertices within event
43  size_t nPrimaryVertices = 0;
44  // number of secondary vertices associated to a primary vertex
45  size_t nSecondaryVertices = 0;
46  // number of particles associated to a vertex (primary + secondary)
47  size_t nParticlesVertex = 0;
48  // total number of particles within event
49  size_t nParticles = 0;
50 
51  for (size_t iGenerate = 0; iGenerate < m_cfg.generators.size(); ++iGenerate) {
52  auto& generate = m_cfg.generators[iGenerate];
53 
54  // generate the number of primary vertices from this generator
55  for (size_t n = generate.multiplicity(rng); 0 < n; --n) {
56  nPrimaryVertices += 1;
57  nSecondaryVertices = 0;
58  nParticlesVertex = 0;
59 
60  // generate primary vertex position
61  auto vertex = generate.vertex(rng);
62  // generate associated process vertices
63  // by convention the first process vertex should contain the
64  // particles associated directly to the primary vertex itself.
65  auto processVertices = generate.process(rng);
66 
67  for (auto& processVertex : processVertices) {
68  nSecondaryVertices += 1;
69  // shift the process vertex to the generated primary vertex position
70  processVertex.position4 += vertex;
71 
72  auto updateParticleInPlace = [&](ActsFatras::Particle& particle) {
73  // only set the primary vertex, leave everything else as-is
74  // using the number of primary vertices as the index ensures
75  // that barcode=0 is not used, since it is typically used elsewhere
76  // to signify elements w/o an associated particle.
77  const auto pid = ActsFatras::Barcode(particle.particleId())
78  .setVertexPrimary(nPrimaryVertices);
79  // move particle to the vertex
80  const auto pos4 = (vertex + particle.position4()).eval();
81  // this changes the particle identity; must reassign.
82  particle = particle.withParticleId(pid).setPosition4(pos4);
83  };
84 
85  for (auto& particle : processVertex.incoming) {
86  updateParticleInPlace(particle);
87  nParticlesVertex += 1;
88  }
89  for (auto& particle : processVertex.outgoing) {
90  updateParticleInPlace(particle);
91  nParticlesVertex += 1;
92  }
93  }
94  nParticles += nParticlesVertex;
95 
96  // append all process vertices to the full event
97  std::move(processVertices.begin(), processVertices.end(),
98  std::back_inserter(event));
99 
100  ACTS_VERBOSE("event=" << ctx.eventNumber << " generator=" << iGenerate
101  << " primary_vertex=" << nPrimaryVertices
102  << " n_secondary_vertices=" << nSecondaryVertices
103  << " n_particles=" << nParticlesVertex);
104  }
105  }
106  // TODO should this reassign the vertex ids?
107  // if not, what is the purpose? can it be removed altogether?
108  if (m_cfg.shuffle) {
109  std::shuffle(event.begin(), event.end(), rng);
110  }
111 
112  ACTS_DEBUG("event=" << ctx.eventNumber
113  << " n_primary_vertices=" << nPrimaryVertices
114  << " n_secondary_vertices=" << event.size()
115  << " n_particles=" << nParticles);
116 
117  // move generated event to the store
118  ctx.eventStore.add(m_cfg.output, std::move(event));
120 }