Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Smearers.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Smearers.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 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 
16 
17 #include <cmath>
18 #include <limits>
19 #include <random>
20 #include <string>
21 #include <tuple>
22 #include <utility>
23 
24 namespace ActsExamples {
25 namespace Digitization {
26 
29 struct Exact {
38  double value, RandomEngine& /*rnd*/) const {
39  return std::pair{value, 0.0};
40  }
41 };
42 
47 struct Gauss {
48  double sigma;
49 
51  Gauss(double sigma_) : sigma{sigma_} {}
52 
60  RandomEngine& rnd) const {
61  std::normal_distribution<> dist{0, sigma};
62  return std::pair{value + dist(rnd), dist.stddev()};
63  }
64 };
65 
70 struct GaussTrunc {
71  double sigma;
72  std::pair<double, double> range = {std::numeric_limits<double>::lowest(),
73  std::numeric_limits<double>::max()};
74 
76  GaussTrunc(double sigma_, const std::pair<double, double>& range_)
77  : sigma{sigma_}, range(range_) {}
78 
86  RandomEngine& rnd) const {
87  std::normal_distribution<> dist{0., sigma};
88  double svalue = value + dist(rnd);
89  if (svalue >= range.first and svalue <= range.second) {
90  return std::pair{svalue, dist.stddev()};
91  }
92  return ActsFatras::DigitizationError::SmearingOutOfRange;
93  }
94 };
95 
100 struct GaussClipped {
101  double sigma;
102 
103  size_t maxAttemps = 1000;
104 
105  std::pair<double, double> range = {std::numeric_limits<double>::lowest(),
106  std::numeric_limits<double>::max()};
107 
109  GaussClipped(double sigma_, const std::pair<double, double>& range_)
110  : sigma{sigma_}, range(range_) {}
111 
121  RandomEngine& rnd) const {
122  std::normal_distribution<> dist{0., sigma};
123  for (size_t attempt = 0; attempt < maxAttemps; ++attempt) {
124  double svalue = value + dist(rnd);
125  if (svalue >= range.first and svalue <= range.second) {
126  return std::pair{svalue, dist.stddev()};
127  }
128  }
129  return ActsFatras::DigitizationError::SmearingError;
130  }
131 };
132 
136 struct Uniform {
138 
140  Uniform(double pitch, const std::pair<double, double>& range_)
141  : binningData(Acts::open, Acts::binX,
142  static_cast<size_t>((range_.second - range_.first) / pitch),
143  range_.first, range_.second) {}
144 
149 
157  RandomEngine& rnd) const {
158  if (binningData.min < value and binningData.max > value) {
159  auto bin = binningData.search(value);
160  auto lower = binningData.boundaries()[bin];
161  auto higher = binningData.boundaries()[bin + 1];
162  std::uniform_real_distribution<> dist{0., 1.};
163  double svalue = lower + (higher - lower) * dist(rnd);
164  return std::pair{svalue, (higher - lower) / std::sqrt(12.)};
165  }
166  return ActsFatras::DigitizationError::SmearingError;
167  }
168 };
169 
173 struct Digital {
175 
177  Digital(double pitch, const std::pair<double, double>& range_)
178  : binningData(Acts::open, Acts::binX,
179  static_cast<size_t>((range_.second - range_.first) / pitch),
180  range_.first, range_.second) {}
181 
186 
194  double value, RandomEngine& /*rnd*/) const {
195  if (binningData.min < value and binningData.max > value) {
196  auto bin = binningData.search(value);
197  auto lower = binningData.boundaries()[bin];
198  auto higher = binningData.boundaries()[bin + 1];
199  double svalue = 0.5 * (lower + higher);
200  return std::pair{svalue, (higher - lower) / std::sqrt(12.)};
201  }
202  return ActsFatras::DigitizationError::SmearingError;
203  }
204 };
205 
206 } // namespace Digitization
207 } // namespace ActsExamples