SND@LHC Software
Loading...
Searching...
No Matches
TGeoMaterialInterface.cc
Go to the documentation of this file.
1/* Copyright 2008-2014, Technische Universitaet Muenchen,
2 Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
3
4 This file is part of GENFIT.
5
6 GENFIT is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 GENFIT is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <TGeoMaterialInterface.h>
21#include <Exception.h>
22
23#include <TGeoMedium.h>
24#include <TGeoMaterial.h>
25#include <TGeoManager.h>
26#include <assert.h>
27#include <math.h>
28
29static const bool debug = false;
30//static const bool debug = true;
31
32namespace genfit {
33
34double MeanExcEnergy_get(int Z);
35double MeanExcEnergy_get(TGeoMaterial*);
36
37
38bool
39TGeoMaterialInterface::initTrack(double posX, double posY, double posZ,
40 double dirX, double dirY, double dirZ){
41 #ifdef DEBUG
42 std::cout << "TGeoMaterialInterface::initTrack. \n";
43 std::cout << "Pos "; TVector3(posX, posY, posZ).Print();
44 std::cout << "Dir "; TVector3(dirX, dirY, dirZ).Print();
45 #endif
46
47 // Move to the new point.
48 bool result = !gGeoManager->IsSameLocation(posX, posY, posZ, kTRUE);
49 // Set the intended direction.
50 gGeoManager->SetCurrentDirection(dirX, dirY, dirZ);
51 return result;
52}
53
54
55void
57 double& Z,
58 double& A,
59 double& radiationLength,
60 double& mEE){
61
62 TGeoMaterial* mat = gGeoManager->GetCurrentVolume()->GetMedium()->GetMaterial();
63
64 density = mat->GetDensity();
65 Z = mat->GetZ();
66 A = mat->GetA();
67 radiationLength = mat->GetRadLen();
68 mEE = MeanExcEnergy_get(mat);
69
70}
71
72
73void
75
76 TGeoMaterial* mat = gGeoManager->GetCurrentVolume()->GetMedium()->GetMaterial();
77
78 parameters.setMaterialProperties(mat->GetDensity(),
79 mat->GetZ(),
80 mat->GetA(),
81 mat->GetRadLen(),
83
84}
85
86
87double
89 const M1x7& stateOrig,
90 double sMax, // signed
91 bool varField)
92{
93 const double delta(1.E-2); // cm, distance limit beneath which straight-line steps are taken.
94 const double epsilon(1.E-1); // cm, allowed upper bound on arch
95 // deviation from straight line
96
97 M1x3 SA;
98 M1x7 state7, oldState7;
99 memcpy(oldState7, stateOrig, sizeof(state7));
100
101 int stepSign(sMax < 0 ? -1 : 1);
102
103 double s = 0; // trajectory length to boundary
104
105 const unsigned maxIt = 300;
106 unsigned it = 0;
107
108 // Initialize the geometry to the current location (set by caller).
109 gGeoManager->FindNextBoundary(fabs(sMax) - s);
110 double safety = gGeoManager->GetSafeDistance();
111 double slDist = gGeoManager->GetStep();
112 double step = slDist;
113
114 while (1) {
115 if (++it > maxIt){
116 Exception exc("TGeoMaterialInterface::findNextBoundary ==> maximum number of iterations exceeded",__LINE__,__FILE__);
117 exc.setFatal();
118 throw exc;
119 }
120
121 // No boundary in sight?
122 if (s + safety > fabs(sMax)) {
123 if (debug)
124 std::cout << " next boundary is further away than sMax \n";
125 return stepSign*(s + safety); //sMax;
126 }
127
128 // Are we at the boundary?
129 if (slDist < delta) {
130 if (debug)
131 std::cout << " very close to the boundary -> return"
132 << " stepSign*(s + slDist) = "
133 << stepSign << "*(" << s + slDist << ")\n";
134 return stepSign*(s + slDist);
135 }
136
137 // We have to find whether there's any boundary on our path.
138
139 // Follow curved arch, then see if we may have missed a boundary.
140 // Always propagate complete way from original start to avoid
141 // inconsistent extrapolations.
142 memcpy(state7, stateOrig, sizeof(state7));
143 rep->RKPropagate(state7, NULL, SA, stepSign*(s + step), varField);
144
145 // Straight line distance² between extrapolation finish and
146 // the end of the previously determined safe segment.
147 double dist2 = (pow(state7[0] - oldState7[0], 2)
148 + pow(state7[1] - oldState7[1], 2)
149 + pow(state7[2] - oldState7[2], 2));
150 // Maximal lateral deviation².
151 double maxDeviation2 = 0.25*(step*step - dist2);
152
153 if (step > safety
154 && maxDeviation2 > epsilon*epsilon) {
155 // Need to take a shorter step to reliably estimate material,
156 // but only if we didn't move by safety. In order to avoid
157 // issues with roundoff we check 'step > safety' instead of
158 // 'step != safety'. If we moved by safety, there couldn't have
159 // been a boundary that we missed along the path, but we could
160 // be on the boundary.
161
162 // Take a shorter step, but never shorter than safety.
163 step = std::max(step / 2, safety);
164 } else {
165 gGeoManager->PushPoint();
166 bool volChanged = initTrack(state7[0], state7[1], state7[2],
167 stepSign*state7[3], stepSign*state7[4],
168 stepSign*state7[5]);
169
170 if (volChanged) {
171 // Move back to start.
172 gGeoManager->PopPoint();
173
174 // Extrapolation may not take the exact step length we asked
175 // for, so it can happen that a requested step < safety takes
176 // us across the boundary. This is then the best estimate we
177 // can get of the distance to the boundary with the stepper.
178 if (step <= safety)
179 return stepSign*(s + step);
180
181 // Volume changed during the extrapolation. Take a shorter
182 // step, but never shorter than safety.
183 step = std::max(step / 2, safety);
184 } else {
185 // we're in the new place, the step was safe, advance
186 s += step;
187
188 memcpy(oldState7, state7, sizeof(state7));
189 gGeoManager->PopDummy(); // Pop stack, but stay in place.
190
191 gGeoManager->FindNextBoundary(fabs(sMax) - s);
192 safety = gGeoManager->GetSafeDistance();
193 step = slDist = gGeoManager->GetStep();
194 }
195 }
196 }
197}
198
199
200double
202
203 gGeoManager->FindNextBoundaryAndStep(sMax);
204 return gGeoManager->GetStep();
205
206}
207
208
209
210
211/*
212Reference for elemental mean excitation energies at:
213http://physics.nist.gov/PhysRefData/XrayMassCoef/tab1.html
214
215Code ported from GEANT 3
216*/
217
218const int MeanExcEnergy_NELEMENTS = 93; // 0 = vacuum, 1 = hydrogen, 92 = uranium
219const double MeanExcEnergy_vals[] = {1.e15, 19.2, 41.8, 40.0, 63.7, 76.0, 78., 82.0, 95.0, 115.0, 137.0, 149.0, 156.0, 166.0, 173.0, 173.0, 180.0, 174.0, 188.0, 190.0, 191.0, 216.0, 233.0, 245.0, 257.0, 272.0, 286.0, 297.0, 311.0, 322.0, 330.0, 334.0, 350.0, 347.0, 348.0, 343.0, 352.0, 363.0, 366.0, 379.0, 393.0, 417.0, 424.0, 428.0, 441.0, 449.0, 470.0, 470.0, 469.0, 488.0, 488.0, 487.0, 485.0, 491.0, 482.0, 488.0, 491.0, 501.0, 523.0, 535.0, 546.0, 560.0, 574.0, 580.0, 591.0, 614.0, 628.0, 650.0, 658.0, 674.0, 684.0, 694.0, 705.0, 718.0, 727.0, 736.0, 746.0, 757.0, 790.0, 790.0, 800.0, 810.0, 823.0, 823.0, 830.0, 825.0, 794.0, 827.0, 826.0, 841.0, 847.0, 878.0, 890.0};
220
221
222double
224 assert(Z >= 0 && Z < MeanExcEnergy_NELEMENTS);
225 return MeanExcEnergy_vals[Z];
226}
227
228
229double
230MeanExcEnergy_get(TGeoMaterial* mat) {
231 if (mat->IsMixture()) {
232 double logMEE = 0.;
233 double denom = 0.;
234 TGeoMixture* mix = (TGeoMixture*)mat;
235 for (int i = 0; i < mix->GetNelements(); ++i) {
236 int index = int(floor((mix->GetZmixt())[i]));
237 logMEE += 1. / (mix->GetAmixt())[i] * (mix->GetWmixt())[i] * (mix->GetZmixt())[i] * log(MeanExcEnergy_get(index));
238 denom += (mix->GetWmixt())[i] * (mix->GetZmixt())[i] * 1. / (mix->GetAmixt())[i];
239 }
240 logMEE /= denom;
241 return exp(logMEE);
242 } else { // not a mixture
243 int index = int(floor(mat->GetZ()));
244 return MeanExcEnergy_get(index);
245 }
246}
247
248
249} /* End of namespace genfit */
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition Exception.h:48
void setFatal(bool b=true)
Set fatal flag.
Definition Exception.h:61
Material properties needed e.g. for material effects calculation.
void setMaterialProperties(const double &density, const double &Z, const double &A, const double &radiationLength, const double &mEE)
AbsTrackRep with 5D track parameterization in plane coordinates: (q/p, u', v', u, v)
Definition RKTrackRep.h:70
double RKPropagate(M1x7 &state7, M7x7 *jacobian, M1x3 &SA, double S, bool varField=true, bool calcOnlyLastRowOfJ=false) const
The actual Runge Kutta propagation.
void getMaterialParameters(double &density, double &Z, double &A, double &radiationLength, double &mEE)
Get material parameters in current material.
double findNextBoundaryAndStepStraight(double sMax)
bool initTrack(double posX, double posY, double posZ, double dirX, double dirY, double dirZ)
Initialize the navigator at given position and with given direction. Returns true if the volume chang...
double findNextBoundary(const RKTrackRep *rep, const M1x7 &state7, double sMax, bool varField=true)
Make a step (following the curvature) until step length sMax or the next boundary is reached....
Matrix inversion tools.
Definition AbsBField.h:29
double M1x7[1 *7]
Definition RKTools.h:36
double MeanExcEnergy_get(int Z)
double M1x3[1 *3]
Definition RKTools.h:33
const int MeanExcEnergy_NELEMENTS
const double MeanExcEnergy_vals[]