ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialCollector.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialCollector.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2020 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>
16 
17 namespace Acts {
18 
20 struct MaterialHit {
21  const Surface* surface = nullptr;
25  double pathLength;
26 };
27 
33  bool detailedCollection = false;
34 
40  struct this_result {
41  std::vector<MaterialHit> collected;
42  double materialInX0 = 0.;
43  double materialInL0 = 0.;
44  };
45 
47 
59  template <typename propagator_state_t, typename stepper_t>
60  void operator()(propagator_state_t& state, const stepper_t& stepper,
61  result_type& result) const {
62  if (state.navigation.currentSurface) {
63  if (state.navigation.currentSurface == state.navigation.targetSurface and
64  not state.navigation.targetReached) {
65  return;
66  }
67 
68  debugLog(state, [&] {
69  std::stringstream dstream;
70  dstream << "Material check on surface ";
71  dstream << state.navigation.currentSurface->geoID();
72  return dstream.str();
73  });
74 
75  if (state.navigation.currentSurface->surfaceMaterial()) {
76  // get the material propertices and only continue
77  const MaterialProperties* mProperties =
78  state.navigation.currentSurface->surfaceMaterial()->material(
79  stepper.position(state.stepping));
80  if (mProperties) {
81  // pre/post/full update
82  double prepofu = 1.;
83  if (state.navigation.startSurface ==
84  state.navigation.currentSurface) {
85  debugLog(state, [&] {
86  return std::string("Update on start surface: post-update mode.");
87  });
88  prepofu =
89  state.navigation.currentSurface->surfaceMaterial()->factor(
90  state.stepping.navDir, postUpdate);
91  } else if (state.navigation.targetSurface ==
92  state.navigation.currentSurface) {
93  debugLog(state, [&] {
94  return std::string("Update on target surface: pre-update mode");
95  });
96  prepofu =
97  state.navigation.currentSurface->surfaceMaterial()->factor(
98  state.stepping.navDir, preUpdate);
99  } else {
100  debugLog(state, [&] {
101  return std::string("Update while pass through: full mode.");
102  });
103  }
104 
105  // the pre/post factor has been applied
106  // now check if there's still something to do
107  if (prepofu == 0.) {
108  debugLog(state, [&] {
109  return std::string("Pre/Post factor set material to zero.");
110  });
111  return;
112  }
113  // more debugging output to the screen
114  debugLog(state, [&] {
115  return std::string("Material properties found for this surface.");
116  });
117 
118  // the path correction from the surface intersection
119  double pCorrection =
120  prepofu * state.navigation.currentSurface->pathCorrection(
121  stepper.position(state.stepping),
122  stepper.direction(state.stepping));
123  // the full material
124  result.materialInX0 += pCorrection * mProperties->thicknessInX0();
125  result.materialInL0 += pCorrection * mProperties->thicknessInL0();
126 
127  debugLog(state, [&] {
128  std::stringstream dstream;
129  dstream << "t/X0 (t/L0) increased to ";
130  dstream << result.materialInX0 << " (";
131  dstream << result.materialInL0 << " )";
132  return dstream.str();
133  });
134 
135  // if configured, record the individual material hits
136  if (detailedCollection) {
137  // create for recording
138  MaterialHit mHit;
139  mHit.surface = state.navigation.currentSurface;
140  mHit.position = stepper.position(state.stepping);
141  mHit.direction = stepper.direction(state.stepping);
142  // get the material & path length
143  mHit.material = mProperties->material();
144  mHit.pathLength = pCorrection * mProperties->thickness();
145  // save if in the result
146  result.collected.push_back(mHit);
147  }
148  }
149  }
150  }
151  }
152 
155  template <typename propagator_state_t>
156  void operator()(propagator_state_t& /*state*/) const {}
157 
158  private:
170  template <typename propagator_state_t>
171  void debugLog(propagator_state_t& state,
172  const std::function<std::string()>& logAction) const {
173  if (state.options.debug) {
174  std::stringstream dstream;
175  dstream << " " << std::setw(state.options.debugPfxWidth);
176  dstream << "material collector"
177  << " | ";
178  dstream << std::setw(state.options.debugMsgWidth) << logAction() << '\n';
179  state.options.debugString += dstream.str();
180  }
181  }
182 };
183 } // namespace Acts