Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Simulator.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Simulator.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 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 
11 #include "Acts/EventData/NeutralParameters.hpp"
16 #include "Acts/Propagator/detail/DebugOutputActor.hpp"
17 #include "Acts/Propagator/detail/StandardAborters.hpp"
19 #include <optional>
20 
21 namespace Fatras {
22 
23 struct VoidDetector {};
24 
38 template <typename charged_propagator_t, typename charged_selector_t,
39  typename charged_interactor_t, typename neutral_propagator_t,
40  typename neutral_selector_t, typename neutral_interactor_t>
41 struct Simulator {
42 
43  Simulator(charged_propagator_t chpropagator, neutral_propagator_t npropagator)
44  : chargedPropagator(std::move(chpropagator)),
45  neutralPropagator(std::move(npropagator)),
46  mlogger(Acts::getDefaultLogger("Simulator", Acts::Logging::INFO)) {}
47 
48  using PhysicsList_t = typename charged_interactor_t::PhysicsList_t;
49  charged_propagator_t chargedPropagator;
50  charged_selector_t chargedSelector;
52 
53  neutral_propagator_t neutralPropagator;
54  neutral_selector_t neutralSelector;
55 
57 
58  std::shared_ptr<const Acts::Logger> mlogger = nullptr;
59 
60  bool debug = false;
61 
63  const Acts::Logger &logger() const { return *mlogger; }
64 
76  template <typename context_t, typename generator_t,
77  typename event_collection_t, typename hit_collection_t>
78  void operator()(context_t &fatrasContext, generator_t &fatrasGenerator,
79  event_collection_t &fatrasEvent,
80  hit_collection_t &fatrasHits) const {
81 
82  // if screen output is required
83  typedef Acts::detail::DebugOutputActor DebugOutput;
84 
85  // Action list, abort list and options
86  typedef Acts::ActionList<charged_interactor_t, DebugOutput>
87  ChargedActionList;
88  typedef Acts::AbortList<Acts::detail::EndOfWorldReached> ChargedAbortList;
90  ChargedOptions;
91 
92  // Action list, abort list and
93  typedef Acts::ActionList<neutral_interactor_t, DebugOutput>
94  NeutralActionList;
95  typedef Acts::AbortList<Acts::detail::EndOfWorldReached> NeutralAbortList;
97  NeutralOptions;
98 
99  // loop over the input events
100  // -> new secondaries will just be attached to that
101  for (auto &vertex : fatrasEvent) {
102  // take care here, the simulation can change the
103  // particle collection
104  for (std::size_t i = 0; i < vertex.outgoing.size(); i++) {
105  // create a local copy since the collection can reallocate and
106  // invalidate any reference.
107  auto particle = vertex.outgoing[i];
108  // charged particle detected and selected
110  // Need to construct them per call to set the particle
111  // Options and configuration
112  ChargedOptions chargedOptions(fatrasContext.geoContext,
113  fatrasContext.magFieldContext);
114  chargedOptions.debug = debug;
115  // Get the charged interactor
116  auto &chargedInteractor =
117  chargedOptions.actionList.template get<charged_interactor_t>();
118  // Result type typedef
119  typedef typename charged_interactor_t::result_type ChargedResult;
120  // Set the generator to guarantee event consistent entires
121  chargedInteractor.generator = &fatrasGenerator;
122  // Put all the additional information into the interactor
123  chargedInteractor.initialParticle = particle;
124  // Set the physics list
125  chargedInteractor.physicsList = physicsList;
126  // Create the kinematic start parameters
127  Acts::CurvilinearParameters start(std::nullopt, particle.position(),
128  particle.momentum(), particle.q(),
129  particle.time());
130  // Run the simulation
131  const auto &result =
132  chargedPropagator.propagate(start, chargedOptions).value();
133  const auto &fatrasResult = result.template get<ChargedResult>();
134  // a) Handle the hits
135  // hits go to the hit collection, particle go to the particle
136  // collection
137  for (const auto &fHit : fatrasResult.simulatedHits) {
138  fatrasHits.insert(fHit);
139  }
140  // b) deal with the particles
141  const auto &simparticles = fatrasResult.outgoing;
142  vertex.outgoing_insert(simparticles);
143  // c) screen output if requested
144  if (debug) {
145  auto &fatrasDebug = result.template get<DebugOutput::result_type>();
146  ACTS_INFO(fatrasDebug.debugString);
147  }
148  } else if (neutralSelector(detector, particle)) {
149  // Options and configuration
150  NeutralOptions neutralOptions(fatrasContext.geoContext,
151  fatrasContext.magFieldContext);
152  neutralOptions.debug = debug;
153  // Get the charged interactor
154  auto &neutralInteractor =
155  neutralOptions.actionList.template get<neutral_interactor_t>();
156  // Result type typedef
157  typedef typename neutral_interactor_t::result_type NeutralResult;
158  // Set the generator to guarantee event consistent entires
159  neutralInteractor.generator = &fatrasGenerator;
160  // Put all the additional information into the interactor
161  neutralInteractor.initialParticle = particle;
162  // Create the kinematic start parameters
163  Acts::NeutralCurvilinearParameters start(
164  std::nullopt, particle.position(), particle.momentum(), 0.);
165  const auto &result =
166  neutralPropagator.propagate(start, neutralOptions).value();
167  auto &fatrasResult = result.template get<NeutralResult>();
168  // a) deal with the particles
169  const auto &simparticles = fatrasResult.outgoing;
170  vertex.outgoing_insert(simparticles);
171  // b) screen output if requested
172  if (debug) {
173  auto &fatrasDebug = result.template get<DebugOutput::result_type>();
174  ACTS_INFO(fatrasDebug.debugString);
175  }
176  } // neutral processing
177  } // loop over particles
178  } // loop over events
179  }
180 };
181 
182 } // namespace Fatras