Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointwiseMaterialInteraction.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PointwiseMaterialInteraction.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 
20 
21 #include <algorithm>
22 #include <cmath>
23 
24 namespace Acts {
25 namespace detail {
26 
30  const Surface* surface = nullptr;
31 
33  const Vector3 pos = Vector3(0., 0., 0);
35  const double time = 0.0;
37  const Vector3 dir = Vector3(0., 0., 0);
39  const float qOverP = 0.0;
41  const float absQ = 0.0;
43  const float momentum = 0.0;
45  const float mass = 0.0;
49  const bool performCovarianceTransport = false;
52 
56  double pathCorrection = 0.;
58  double variancePhi = 0.;
60  double varianceTheta = 0.;
62  double varianceQoverP = 0.;
64  double Eloss = 0.;
66  double nextP = 0.;
67 
76  template <typename propagator_state_t, typename stepper_t>
78  const propagator_state_t& state,
79  const stepper_t& stepper)
80  : surface(sSurface),
81  pos(stepper.position(state.stepping)),
82  time(stepper.time(state.stepping)),
83  dir(stepper.direction(state.stepping)),
84  qOverP(stepper.qOverP(state.stepping)),
85  absQ(stepper.particleHypothesis(state.stepping).absoluteCharge()),
86  momentum(stepper.absoluteMomentum(state.stepping)),
87  mass(stepper.particleHypothesis(state.stepping).mass()),
88  absPdg(stepper.particleHypothesis(state.stepping).absolutePdg()),
89  performCovarianceTransport(state.stepping.covTransport),
90  navDir(state.options.direction) {}
91 
102  template <typename propagator_state_t, typename navigator_t>
104  const propagator_state_t& state, const navigator_t& navigator,
105  MaterialUpdateStage updateStage = MaterialUpdateStage::FullUpdate) {
106  // We are at the start surface
107  if (surface == navigator.startSurface(state.navigation)) {
108  updateStage = MaterialUpdateStage::PostUpdate;
109  // Or is it the target surface ?
110  } else if (surface == navigator.targetSurface(state.navigation)) {
111  updateStage = MaterialUpdateStage::PreUpdate;
112  }
113 
114  // Retrieve the material properties
115  slab = navigator.currentSurface(state.navigation)
116  ->surfaceMaterial()
117  ->materialSlab(pos, navDir, updateStage);
118 
119  // Correct the material properties for non-zero incidence
120  pathCorrection = surface->pathCorrection(state.geoContext, pos, dir);
122 
123  // Get the surface material & properties from them
124  return slab;
125  }
126 
132  void evaluatePointwiseMaterialInteraction(bool multipleScattering,
133  bool energyLoss);
134 
143  template <typename propagator_state_t, typename stepper_t>
144  void updateState(propagator_state_t& state, const stepper_t& stepper,
145  NoiseUpdateMode updateMode = addNoise) {
146  // in forward(backward) propagation, energy decreases(increases) and
147  // variances increase(decrease)
148  const auto nextE = std::hypot(mass, momentum) - Eloss * navDir;
149  // put particle at rest if energy loss is too large
150  nextP = (mass < nextE) ? std::sqrt(nextE * nextE - mass * mass) : 0;
151  // minimum momentum below which we will not push particles via material
152  // update
153  // TODO 10 MeV might be quite low and we should make this configurable
154  static constexpr double minP = 10 * Acts::UnitConstants::MeV;
155  nextP = std::max(minP, nextP);
156  // update track parameters and covariance
157  stepper.update(state.stepping, pos, dir,
159  state.stepping.cov(eBoundPhi, eBoundPhi) = updateVariance(
160  state.stepping.cov(eBoundPhi, eBoundPhi), variancePhi, updateMode);
161  state.stepping.cov(eBoundTheta, eBoundTheta) =
162  updateVariance(state.stepping.cov(eBoundTheta, eBoundTheta),
163  varianceTheta, updateMode);
164  state.stepping.cov(eBoundQOverP, eBoundQOverP) =
165  updateVariance(state.stepping.cov(eBoundQOverP, eBoundQOverP),
166  varianceQoverP, updateMode);
167  }
168 
169  private:
175  void covarianceContributions(bool multipleScattering, bool energyLoss);
176 
184  double updateVariance(double variance, double change,
185  NoiseUpdateMode updateMode = addNoise) const;
186 };
187 
188 } // namespace detail
189 } // end of namespace Acts