37 const AmgSymMatrix(5)* measuredTrackCov = trackParameters->covariance();
39 if (!measuredTrackCov) {
44 const double p = globalMomentum.mag();
45 double pathcorrection = 1.;
46 if (materialProperties.
thickness() != 0) {
47 pathcorrection = pathLength / materialProperties.
thickness();
49 const double t = pathcorrection * materialProperties.
thicknessInX0();
51 const double E = std::sqrt(p * p + m * m);
56 const double sinTheta = std::sin(trackParameters->parameters()[
Trk::theta]);
58 cache.
deltaPhiCov = angularVariation / (sinTheta * sinTheta);
64constexpr double s_singleGaussianRange = 0.0001;
65constexpr double s_lowerRange = 0.002;
66constexpr double s_xOverRange = 0.10;
67constexpr double s_upperRange = 0.20;
68constexpr double s_componentMeanCut = 0.0;
71using polyArray = std::array<BH::Polynomial, GSFConstants::maxNumberofMatComponents>;
76inline constexpr double
77hornerEvaluate(
const std::array<double, N>&
a,
const double&
x)
79 constexpr size_t order =
N - 1;
80 if constexpr (
order == 0) {
82 }
else if constexpr (
order == 1) {
83 return a[0] *
x +
a[1];
84 }
else if constexpr (
order == 2) {
85 return (
a[0] *
x +
a[1]) *
x +
a[2];
86 }
else if constexpr (
order == 3) {
87 return ((
a[0] *
x +
a[1]) *
x +
a[2]) *
x +
a[3];
88 }
else if constexpr (
order == 4) {
89 return (((
a[0] *
x +
a[1]) *
x +
a[2]) *
x +
a[3]) *
x +
a[4];
90 }
else if constexpr (
order == 5) {
91 return ((((
a[0] *
x +
a[1]) *
x +
a[2]) *
x +
a[3]) *
x +
a[4]) *
x +
a[5];
94 ((((
a[0] *
x +
a[1]) *
x +
a[2]) *
x +
a[3]) *
x +
a[4]) *
x +
a[5];
95 for (
size_t i = 6;
i <
N; ++
i) {
103logisticFunction(
const double x)
105 return 1. / (1. + std::exp(-
x));
110correctWeights(BH::MixtureParameters& mixture,
const int numberOfComponents)
112 if (numberOfComponents < 1) {
116 double weightSum(0.);
117 for (
int i = 0;
i < numberOfComponents; ++
i) {
118 weightSum += mixture[
i].weight;
120 const double norm = 1. / weightSum;
122 for (
int i = 0;
i < numberOfComponents; ++
i) {
123 mixture[
i].weight *=
norm;
128getTransformedMixtureParameters(
129 const std::array<BH::Polynomial, GSFConstants::maxNumberofMatComponents>& polynomialWeights,
130 const std::array<BH::Polynomial, GSFConstants::maxNumberofMatComponents>& polynomialMeans,
131 const std::array<BH::Polynomial, GSFConstants::maxNumberofMatComponents>& polynomialVariances,
132 const double pathlengthInX0,
133 const int numberOfComponents)
135 BH::MixtureParameters mixture{};
137 for (
int i = 0;
i < numberOfComponents; ++
i) {
138 const double updatedWeight = hornerEvaluate(polynomialWeights[i], pathlengthInX0);
139 const double updatedMean = hornerEvaluate(polynomialMeans[i], pathlengthInX0);
140 const double updatedVariance = hornerEvaluate(polynomialVariances[i], pathlengthInX0);
141 mixture[
i] = { logisticFunction(updatedWeight),
142 logisticFunction(updatedMean),
143 std::exp(updatedVariance) };
153inline constexpr bool inRange(
int var,
int lo,
int hi) {
154 return ((var <= hi) and (var >= lo));
157BH::Polynomial readPolynomial(std::ifstream& fin) {
158 BH::Polynomial poly{};
161 throw std::logic_error(
"Reached end of stream but still expecting data.");
172 polyArray variances{};
173 int numberOfComponents{};
177readPolys fillFromFile(
const std::string& fileName) {
182 std::ifstream
fin(filename);
184 std::ostringstream
ss;
186 throw std::logic_error(
ss.str());
191 int orderPolynomial = 0;
192 fin >> orderPolynomial;
195 std::ostringstream
ss;
196 ss <<
"numberOfComponents Parameter out of range 0- "
198 <<
result.numberOfComponents;
199 throw std::logic_error(
ss.str());
202 std::ostringstream
ss;
203 ss <<
"orderPolynomial order != "
205 throw std::logic_error(
ss.str());
209 int componentIndex = 0;
210 for (; componentIndex <
result.numberOfComponents; ++componentIndex) {
211 result.weights[componentIndex] = readPolynomial(fin);
212 result.means[componentIndex] = readPolynomial(fin);
213 result.variances[componentIndex] = readPolynomial(fin);
222 const std::string& parameterisationFileName,
223 const std::string& parameterisationFileNameHighX0) {
226 const std::string resolvedFileName =
228 if (resolvedFileName.empty()) {
229 std::ostringstream
ss;
230 ss <<
"Parameterisation file : " << parameterisationFileName
232 throw std::logic_error(
ss.str());
235 readPolys readin = fillFromFile(resolvedFileName);
243 const std::string resolvedFileName =
245 if (resolvedFileName.empty()) {
246 std::ostringstream
ss;
247 ss <<
"Parameterisation file : " << parameterisationFileNameHighX0
249 throw std::logic_error(
ss.str());
251 readPolys readin = fillFromFile(resolvedFileName);
258 std::ostringstream
ss;
259 ss <<
" numberOfComponentsHighX0 != numberOfComponents";
260 throw std::logic_error(
ss.str());
277 scattering(cache_multipleScatter, componentParameters, materialProperties, pathLength);
291 cache_energyLoss.
elements[0] = { 1, 0, 0 };
298 for (
int i = 0; i < cache_energyLoss.
numElements; ++i) {
303 const double covPhi = cache_multipleScatter.
deltaPhiCov;
305 const double covQoverP = cache_energyLoss.
elements[i].deltaQOvePCov;
311 0, 0, 0, covTheta, 0,
312 0, 0, 0, 0, covQoverP;
337 const double radiationLength = materialProperties.
x0();
338 const double momentum = globalMomentum.mag();
339 double pathlengthInX0 = pathLength / radiationLength;
341 if (pathlengthInX0 < s_singleGaussianRange) {
349 if (pathlengthInX0 < s_lowerRange) {
350 const double meanZ = std::exp(-1. * pathlengthInX0);
353 std::exp(-1. * pathlengthInX0 * std::log(3.) / std::log(2.)) -
354 std::exp(-2. * pathlengthInX0);
356 double varQoverP(0.);
358 deltaP =
sign * momentum * (1. - meanZ);
359 varQoverP = 1. / (meanZ * meanZ * momentum * momentum) * varZ;
361 deltaP =
sign * momentum * (1. / meanZ - 1.);
362 varQoverP = varZ / (momentum * momentum);
364 cache.
elements[0] = { 1., deltaP, varQoverP };
369 if (pathlengthInX0 > s_upperRange) {
370 pathlengthInX0 = s_upperRange;
375 if (pathlengthInX0 > s_xOverRange) {
390 int componentIndex = 0;
391 double weightToBeRemoved(0.);
392 int componentWithHighestMean(0);
395 if (mixture[componentIndex].
mean > mixture[componentWithHighestMean].
mean) {
396 componentWithHighestMean = componentIndex;
398 if (mixture[componentIndex].
mean >= s_componentMeanCut) {
401 weightToBeRemoved += mixture[componentIndex].weight;
406 double varianceInverseMomentum = 0;
409 if (mixture[componentIndex].
mean < s_componentMeanCut) {
413 double weight = mixture[componentIndex].weight;
414 if (componentIndex == componentWithHighestMean) {
415 weight += weightToBeRemoved;
420 deltaP = momentum * (mixture[componentIndex].mean - 1.);
421 const double f = 1. / (momentum * mixture[componentIndex].mean);
422 varianceInverseMomentum = f * f * mixture[componentIndex].variance;
424 deltaP = momentum * (1. / mixture[componentIndex].mean - 1.);
425 varianceInverseMomentum = mixture[componentIndex].variance / (momentum * momentum);
431 varianceInverseMomentum };
#define AmgSymMatrix(dim)
bool inRange(const double *boundaries, const double value, const double tolerance=0.02)
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialMeansHighX0
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialVariances
int m_BHnumberOfComponentsHighX0
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialVariancesHighX0
void BetheHeitler(GsfMaterial::EnergyLoss &cache, const ComponentParameters &componentParameters, const MaterialProperties &materialProperties, double pathLenght, PropDirection direction=anyDirection) const
void compute(GsfMaterial::Combined &, const Trk::ComponentParameters &, const Trk::MaterialProperties &, double, Trk::PropDirection=anyDirection) const
ElectronCombinedMaterialEffects(const std::string ¶meterisationFileName, const std::string ¶meterisationFileNameHighX0)
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialWeightsHighX0
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialWeights
int m_BHnumberOfComponents
std::array< Polynomial, GSFConstants::maxNumberofMatComponents > m_BHpolynomialMeans
std::array< ComponentValues, GSFConstants::maxNumberofMatComponents > MixtureParameters
Material with information about thickness of material.
float thicknessInX0() const
Return the radiationlength fraction.
float x0() const
Return the radiation length.
float thickness() const
Return the thickness in mm.
const Amg::Vector3D & momentum() const
Access method for the momentum.
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr int8_t polynomialCoefficients
Number of coefficients for the polynomials, parametrizing the mean,variace, weights of the Gaussian c...
constexpr int8_t maxNumberofMatComponents
Maximum number of Gaussian components for the material effects description.
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
PropDirection
PropDirection, enum for direction of the propagation.
ParametersBase< TrackParametersDim, Charged > TrackParameters
Helper struct for combined material effects, multicomponent description.
std::array< double, GSFConstants::maxNumberofMatComponents > deltaPs
std::array< double, GSFConstants::maxNumberofMatComponents > weights
std::array< AmgSymMatrix(5), GSFConstants::maxNumberofMatComponents > covariances
Helper struct for energy loss effects, multicomponent description.
std::array< element, GSFConstants::maxNumberofMatComponents > elements
Helper struct for multiple scattering effects single component description.
std::unique_ptr< Trk::TrackParameters > params
static double sigmaMS(double dInX0, double p, double beta)
multiple scattering as function of dInX0