EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FatrasAlgorithm.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FatrasAlgorithm.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017 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 
9 #pragma once
10 
16 
17 #include <memory>
18 #include <string>
19 
20 namespace ActsExamples {
21 
25 template <typename simulator_t>
26 class FatrasAlgorithm final : public BareAlgorithm {
27  public:
28  struct Config {
30  std::string inputParticles;
34  std::string outputParticlesFinal;
36  std::string outputHits;
38  simulator_t simulator;
40  std::shared_ptr<const RandomNumbers> randomNumbers;
41 
43  Config(simulator_t&& simulator_) : simulator(std::move(simulator_)) {}
44  };
45 
51  : ActsExamples::BareAlgorithm("FatrasAlgorithm", lvl),
52  m_cfg(std::move(cfg)) {
53  ACTS_DEBUG("hits on sensitive surfaces: "
54  << m_cfg.simulator.charged.selectHitSurface.sensitive);
55  ACTS_DEBUG("hits on material surfaces: "
56  << m_cfg.simulator.charged.selectHitSurface.material);
57  ACTS_DEBUG("hits on passive surfaces: "
58  << m_cfg.simulator.charged.selectHitSurface.passive);
59  }
60 
65  const AlgorithmContext& ctx) const final override {
66  // read input containers
67  const auto& inputParticles =
68  ctx.eventStore.get<SimParticleContainer>(m_cfg.inputParticles);
69  // prepare output containers
70  SimParticleContainer::sequence_type particlesInitialUnordered;
71  SimParticleContainer::sequence_type particlesFinalUnordered;
72  SimHitContainer::sequence_type hitsUnordered;
73  // reserve appropriate resources
74  constexpr auto meanHitsPerParticle = 16u;
75  particlesInitialUnordered.reserve(inputParticles.size());
76  particlesFinalUnordered.reserve(inputParticles.size());
77  hitsUnordered.reserve(meanHitsPerParticle * inputParticles.size());
78 
79  // run the simulation w/ a local random generator
80  auto rng = m_cfg.randomNumbers->spawnGenerator(ctx);
81  auto ret = m_cfg.simulator.simulate(
82  ctx.geoContext, ctx.magFieldContext, rng, inputParticles,
83  particlesInitialUnordered, particlesFinalUnordered, hitsUnordered);
84  // fatal error leads to panic
85  if (not ret.ok()) {
86  ACTS_FATAL("event " << ctx.eventNumber << " simulation failed with error "
87  << ret.error());
88  return ProcessCode::ABORT;
89  }
90  // failed particles are just logged. assumes that failed particles are due
91  // to edge-cases representing a tiny fraction of the event; not due to a
92  // fundamental issue.
93  for (const auto& failed : ret.value()) {
94  ACTS_ERROR("event " << ctx.eventNumber << " particle " << failed.particle
95  << " failed to simulate with error " << failed.error
96  << ": " << failed.error.message());
97  }
98  // TODO is there a point where too many failed particles or failed particles
99  // of a particular type (e.g. from hard interaction or any primary
100  // particle) should also lead to a panic?
101 
102  ACTS_DEBUG(inputParticles.size() << " input particles");
103  ACTS_DEBUG(particlesInitialUnordered.size()
104  << " simulated particles (initial state)");
105  ACTS_DEBUG(particlesFinalUnordered.size()
106  << " simulated particles (final state)");
107  ACTS_DEBUG(hitsUnordered.size() << " hits");
108 
109  // restore ordering for output containers
110  SimParticleContainer particlesInitial;
111  SimParticleContainer particlesFinal;
112  SimHitContainer hits;
113  particlesInitial.adopt_sequence(std::move(particlesInitialUnordered));
114  particlesFinal.adopt_sequence(std::move(particlesFinalUnordered));
115  hits.adopt_sequence(std::move(hitsUnordered));
116 
117  // store ordered output containers
118  ctx.eventStore.add(m_cfg.outputParticlesInitial,
119  std::move(particlesInitial));
120  ctx.eventStore.add(m_cfg.outputParticlesFinal, std::move(particlesFinal));
121  ctx.eventStore.add(m_cfg.outputHits, std::move(hits));
122 
124  }
125 
126  private:
128 };
129 
130 } // namespace ActsExamples