ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialInteractor.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialInteractor.hpp
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 
9 #pragma once
10 
11 #include <sstream>
12 
18 #include "Acts/Utilities/Units.hpp"
19 
20 namespace Acts {
21 
27  Vector3D position = Vector3D(0., 0., 0);
29  double time = 0.0;
31  Vector3D direction = Vector3D(0., 0., 0);
33  double deltaP = 0.0;
35  double sigmaPhi2 = 0.0;
37  double sigmaTheta2 = 0.0;
39  double sigmaQoP2 = 0.0;
41  const Surface* surface = nullptr;
43  const TrackingVolume* volume = nullptr;
45  bool updatedVolumeStep = false;
48  double pathCorrection = 1.;
51 };
52 
58  bool multipleScattering = true;
60  bool energyLoss = true;
62  bool recordInteractions = false;
63 
67  struct Result {
68  // The accumulated materialInX0
69  double materialInX0 = 0.;
71  double materialInL0 = 0.;
73  std::vector<MaterialInteraction> materialInteractions;
74  };
76 
91  template <typename propagator_state_t, typename stepper_t>
92  void operator()(propagator_state_t& state, const stepper_t& stepper,
93  result_type& result) const {
94  // In case of Volume material update the result of the previous step
95  if (recordInteractions && !result.materialInteractions.empty() &&
96  result.materialInteractions.back().volume != nullptr &&
97  result.materialInteractions.back().updatedVolumeStep == false) {
98  UpdateResult(state, stepper, result);
99  }
100 
101  // If we are on target, everything should have been done
102  if (state.navigation.targetReached) {
103  return;
104  }
105  // Do nothing if nothing is what is requested.
107  return;
108  }
109  // We only have material interactions if there is potential material
110  const Surface* surface = state.navigation.currentSurface;
111  const TrackingVolume* volume = state.navigation.currentVolume;
112 
113  if (not(surface and surface->surfaceMaterial()) and
114  not(volume and volume->volumeMaterial())) {
115  return;
116  }
117 
118  if (surface and surface->surfaceMaterial()) {
119  // Prepare relevant input particle properties
120  detail::PointwiseMaterialInteraction d(surface, state, stepper);
121 
122  // Determine the effective traversed material and its properties
123  // Material exists but it's not real, i.e. vacuum; there is nothing to do
124  if (not d.evaluateMaterialProperties(state)) {
125  return;
126  }
127 
128  // Evaluate the material effects
130 
131  if (energyLoss) {
132  debugLog(state, [=] {
133  using namespace UnitLiterals;
134  std::stringstream dstream;
135  dstream << d.slab;
136  dstream << " pdg=" << d.pdg;
137  dstream << " mass=" << d.mass / 1_MeV << "MeV";
138  dstream << " momentum=" << d.momentum / 1_GeV << "GeV";
139  dstream << " energyloss=" << d.Eloss / 1_MeV << "MeV";
140  return dstream.str();
141  });
142  }
143 
144  // To integrate process noise, we need to transport
145  // the covariance to the current position in space
147  stepper.covarianceTransport(state.stepping);
148  }
149  // Apply the material interactions
150  d.updateState(state, stepper);
151  // Record the result
152  recordResult(d, result);
153  } else if (recordInteractions && volume and volume->volumeMaterial()) {
154  // Prepare relevant input particle properties
155  detail::VolumeMaterialInteraction d(volume, state, stepper);
156  // Determine the effective traversed material and its properties
157  // Material exists but it's not real, i.e. vacuum; there is nothing to do
158  if (not d.evaluateMaterialProperties(state)) {
159  return;
160  }
161  // Record the result
162  recordResult(d, result);
163  }
164  }
165 
167  template <typename propagator_state_t>
168  void operator()(propagator_state_t& /* unused */) const {}
169 
170  private:
176  result_type& result) const {
177  result.materialInX0 += d.slab.thicknessInX0();
178  result.materialInL0 += d.slab.thicknessInL0();
179  // Record the interaction if requested
180  if (recordInteractions) {
182  mi.position = d.pos;
183  mi.time = d.time;
184  mi.direction = d.dir;
185  mi.deltaP = d.nextP - d.momentum;
186  mi.sigmaPhi2 = d.variancePhi;
187  mi.sigmaTheta2 = d.varianceTheta;
188  mi.sigmaQoP2 = d.varianceQoverP;
189  mi.surface = d.surface;
190  mi.volume = nullptr;
192  mi.materialProperties = d.slab;
193  result.materialInteractions.push_back(std::move(mi));
194  }
195  }
196 
202  result_type& result) const {
203  // Record the interaction
205  mi.position = d.pos;
206  mi.time = d.time;
207  mi.direction = d.dir;
208  mi.sigmaPhi2 = d.variancePhi;
209  mi.sigmaTheta2 = d.varianceTheta;
210  mi.sigmaQoP2 = d.varianceQoverP;
211  mi.surface = nullptr;
212  mi.volume = d.volume;
214  mi.materialProperties = d.slab;
215  result.materialInteractions.push_back(std::move(mi));
216  }
217 
222  template <typename propagator_state_t, typename stepper_t>
223  void UpdateResult(propagator_state_t& state, const stepper_t& stepper,
224  result_type& result) const {
225  // Update the previous interaction
226  Vector3D shift = stepper.position(state.stepping) -
227  result.materialInteractions.back().position;
228  double momentum = stepper.direction(state.stepping).norm();
229  result.materialInteractions.back().deltaP =
230  momentum - result.materialInteractions.back().direction.norm();
231  result.materialInteractions.back().materialProperties.scaleThickness(
232  shift.norm());
233  result.materialInteractions.back().updatedVolumeStep = true;
234  result.materialInX0 +=
235  result.materialInteractions.back().materialProperties.thicknessInX0();
236  result.materialInL0 +=
237  result.materialInteractions.back().materialProperties.thicknessInL0();
238  }
239 
251  template <typename propagator_state_t>
252  void debugLog(propagator_state_t& state,
253  const std::function<std::string()>& logAction) const {
254  if (state.options.debug) {
255  std::stringstream dstream;
256  dstream << " " << std::setw(state.options.debugPfxWidth);
257  dstream << "material interaction"
258  << " | ";
259  dstream << std::setw(state.options.debugMsgWidth) << logAction() << '\n';
260  state.options.debugString += dstream.str();
261  }
262  }
263 };
264 
267 
271 using RecordedMaterialTrack =
272  std::pair<std::pair<Acts::Vector3D, Acts::Vector3D>, RecordedMaterial>;
273 
274 } // namespace Acts