EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FatrasSimulationBase.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FatrasSimulationBase.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 
45 
46 #include <boost/program_options.hpp>
47 
48 namespace {
49 
51 struct HitSurfaceSelector {
52  bool sensitive = false;
53  bool material = false;
54  bool passive = false;
55 
57  bool operator()(const Acts::Surface& surface) const {
58  if (sensitive and surface.associatedDetectorElement()) {
59  return true;
60  }
61  if (material and surface.surfaceMaterial()) {
62  return true;
63  }
64  if (passive) {
65  return true;
66  }
67  return false;
68  }
69 };
70 
82 template <typename magnetic_field_t>
83 void setupSimulationAlgorithms(
84  const ActsExamples::Options::Variables& variables,
85  ActsExamples::Sequencer& sequencer,
86  std::shared_ptr<const ActsExamples::RandomNumbers> randomNumbers,
87  std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
88  magnetic_field_t&& magneticField) {
89  // Read the log level
90  Acts::Logging::Level logLevel =
92 
93  // Convert generated events to selected particles
94  auto select = ActsExamples::ParticleSelector::readConfig(variables);
95  select.inputParticles = "particles_generated";
96  select.outputParticles = "particles_selected";
97  sequencer.addAlgorithm(
98  std::make_shared<ActsExamples::ParticleSelector>(select, logLevel));
99 
100  // setup propagator-related types
101  // use the default navigation
102  using Navigator = Acts::Navigator;
103  // propagate charged particles numerically in the given magnetic field
104  using ChargedStepper = Acts::EigenStepper<magnetic_field_t>;
105  using ChargedPropagator = Acts::Propagator<ChargedStepper, Navigator>;
106  // propagate neutral particles with just straight lines
107  using NeutralStepper = Acts::StraightLineStepper;
108  using NeutralPropagator = Acts::Propagator<NeutralStepper, Navigator>;
109 
110  // setup simulator-related types
112  // charged particles w/ standard em physics list and selectable hits
113  using ChargedSelector =
115  using ChargedSimulator = ActsFatras::ParticleSimulator<
117  HitSurfaceSelector>;
118  // neutral particles w/o physics and no hits
119  using NeutralSelector =
121  using NeutralSimulator = ActsFatras::ParticleSimulator<
123  // full simulator type for charged and neutrals
124  using Simulator = ActsFatras::Simulator<ChargedSelector, ChargedSimulator,
125  NeutralSelector, NeutralSimulator>;
126  // final algorihm type
127  using SimulationAlgorithm = ActsExamples::FatrasAlgorithm<Simulator>;
128 
129  // construct the simulator
130  Navigator navigator(trackingGeometry);
131  // construct the charged simulator
132  ChargedStepper chargedStepper(std::move(magneticField));
133  ChargedPropagator chargedPropagator(std::move(chargedStepper), navigator);
134  ChargedSimulator chargedSimulator(std::move(chargedPropagator), logLevel);
135  // construct the neutral simulator
136  NeutralStepper neutralStepper;
137  NeutralPropagator neutralPropagator(std::move(neutralStepper), navigator);
138  NeutralSimulator neutralSimulator(std::move(neutralPropagator), logLevel);
139  // construct the combined simulator
140  Simulator simulator(std::move(chargedSimulator), std::move(neutralSimulator));
141 
142  // construct/add the simulation algorithm
143  auto fatras =
144  ActsExamples::Options::readFatrasConfig(variables, std::move(simulator));
145  fatras.inputParticles = select.outputParticles;
146  fatras.outputParticlesInitial = "particles_initial";
147  fatras.outputParticlesFinal = "particles_final";
148  fatras.outputHits = "hits";
149  fatras.randomNumbers = randomNumbers;
150  sequencer.addAlgorithm(
151  std::make_shared<SimulationAlgorithm>(fatras, logLevel));
152 
153  // Output directory
154  const auto outputDir = ActsExamples::ensureWritableDirectory(
155  variables["output-dir"].template as<std::string>());
156 
157  // Write simulation information as CSV files
158  if (variables["output-csv"].template as<bool>()) {
160  writeInitial.inputParticles = fatras.outputParticlesInitial;
161  writeInitial.outputDir = outputDir;
162  writeInitial.outputStem = fatras.outputParticlesInitial;
163  sequencer.addWriter(std::make_shared<ActsExamples::CsvParticleWriter>(
164  writeInitial, logLevel));
166  writeFinal.inputParticles = fatras.outputParticlesFinal;
167  writeFinal.outputDir = outputDir;
168  writeFinal.outputStem = fatras.outputParticlesFinal;
169  sequencer.addWriter(std::make_shared<ActsExamples::CsvParticleWriter>(
170  writeFinal, logLevel));
171  }
172 
173  // Write simulation information as ROOT files
174  if (variables["output-root"].template as<bool>()) {
175  // write initial simulated particles
177  writeInitial.inputParticles = fatras.outputParticlesInitial;
178  writeInitial.filePath = ActsExamples::joinPaths(
179  outputDir, fatras.outputParticlesInitial + ".root");
180  sequencer.addWriter(std::make_shared<ActsExamples::RootParticleWriter>(
181  writeInitial, logLevel));
182 
183  // write final simulated particles
185  writeFinal.inputParticles = fatras.outputParticlesFinal;
186  writeFinal.filePath = ActsExamples::joinPaths(
187  outputDir, fatras.outputParticlesFinal + ".root");
188  sequencer.addWriter(std::make_shared<ActsExamples::RootParticleWriter>(
189  writeFinal, logLevel));
190 
191  // write simulated hits
193  writeHits.inputSimulatedHits = fatras.outputHits;
194  writeHits.filePath =
195  ActsExamples::joinPaths(outputDir, fatras.outputHits + ".root");
196  sequencer.addWriter(
197  std::make_shared<ActsExamples::RootSimHitWriter>(writeHits, logLevel));
198  }
199 }
200 
201 } // namespace
202 
204  const ActsExamples::Options::Variables& variables,
205  ActsExamples::Sequencer& sequencer,
206  std::shared_ptr<const RandomNumbers> randomNumbers,
207  std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry) {
208  auto magneticFieldVariant = ActsExamples::Options::readBField(variables);
209  std::visit(
210  [&](auto&& inputField) {
211  using magnetic_field_t =
212  typename std::decay_t<decltype(inputField)>::element_type;
214  setupSimulationAlgorithms(variables, sequencer, randomNumbers,
215  trackingGeometry, std::move(magneticField));
216  },
217  magneticFieldVariant);
218 }