17 speed(SpeedOfLight * bg /
sqrt(1. + bg * bg)),
26 datafile(
"SiM0invw.inv"),
36 const double t0,
const double dx0,
const double dy0,
41 std::cerr <<
className <<
"::NewTrack:\n";
42 std::cerr <<
" Sensor is not defined.\n";
49 if (!LoadCrossSectionTable(datafile)) {
50 std::cerr <<
className <<
"::NewTrack:\n";
51 std::cerr <<
" Cross-section table could not be loaded.\n";
60 std::cerr <<
className <<
"::NewTrack:\n";
61 std::cerr <<
" No medium at initial position.\n";
67 if (medium->
GetName() !=
"Si") {
68 std::cerr <<
className <<
"::NewTrack:" << std::endl;
69 std::cerr <<
" Medium at initial position is not silicon.\n";
76 std::cerr <<
className <<
"::NewTrack:\n";
77 std::cerr <<
" Medium at initial position is not ionisable.\n";
89 const double d =
sqrt(dx0 * dx0 + dy0 * dy0 + dz0 * dz0);
94 const double stheta =
sqrt(1. - ctheta * ctheta);
95 dx =
cos(phi) * stheta;
96 dy =
sin(phi) * stheta;
108 speed = SpeedOfLight *
GetBeta();
109 SelectCrossSectionTable();
117 double& tcls,
int& n,
double& e,
double& extra) {
119 if (!isInitialised || !isInMedium)
return false;
139 std::cout <<
className <<
"::GetCluster:\n";
140 std::cout <<
" Particle left the medium.\n";
148 std::cout <<
className <<
"::GetCluster:\n";
149 std::cout <<
" Particle left the medium.\n";
155 const int j = int(u);
157 e = 0. + u * cdf[0][iCdf];
158 }
else if (j >= nCdfEntries) {
159 e = cdf[nCdfEntries - 1][iCdf];
161 e = cdf[j - 1][iCdf] + (u - j) * (cdf[j][iCdf] - cdf[j - 1][iCdf]);
169 const int nEntries = 38;
171 const double tabBg[nEntries] = {
172 0.316, 0.398, 0.501, 0.631, 0.794, 1.000, 1.259, 1.585,
173 1.995, 2.512, 3.162, 3.981, 5.012, 6.310, 7.943, 10.000,
174 12.589, 15.849, 19.953, 25.119, 31.623, 39.811, 50.119, 63.096,
175 79.433, 100.000, 125.893, 158.489, 199.526, 251.189, 316.228, 398.107,
176 501.187, 630.958, 794.329, 1000.000, 1258.926, 1584.894};
178 const double tabImfp[nEntries] = {
179 30.32496, 21.14965, 15.06555, 11.05635, 8.43259, 6.72876, 5.63184,
180 4.93252, 4.49174, 4.21786, 4.05090, 3.95186, 3.89531, 3.86471,
181 3.84930, 3.84226, 3.83952, 3.83887, 3.83912, 3.83970, 3.84035,
182 3.84095, 3.84147, 3.84189, 3.84223, 3.84249, 3.84269, 3.84283,
183 3.84293, 3.84300, 3.84304, 3.84308, 3.84310, 3.84311, 3.84312,
184 3.84313, 3.84313, 3.84314};
190 std::cerr <<
className <<
"::GetClusterDensity:\n";
191 std::cerr <<
" Bg is below the tabulated range.\n";
193 return tabImfp[0] * 1.e4;
194 }
else if (bg > tabBg[nEntries - 1]) {
195 return tabImfp[nEntries - 1] * 1.e4;
200 int iUp = nEntries - 1;
202 while (iUp - iLow > 1) {
203 iM = (iUp + iLow) >> 1;
204 if (bg >= tabBg[iM]) {
211 if (
fabs(bg - tabBg[iLow]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
212 return tabImfp[iLow] * 1.e4;
214 if (
fabs(bg - tabBg[iUp]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
215 return tabImfp[iUp] * 1.e4;
219 const double logX0 = log(tabBg[iLow]);
220 const double logX1 = log(tabBg[iUp]);
221 const double logY0 = log(tabImfp[iLow]);
222 const double logY1 = log(tabImfp[iUp]);
223 double d = logY0 + (log(bg) - logX0) * (logY1 - logY0) / (logX1 - logX0);
224 return 1.e4 *
exp(d);
229 const int nEntries = 51;
231 const double tabBg[nEntries] = {
232 0.316, 0.398, 0.501, 0.631, 0.794, 1.000, 1.259,
233 1.585, 1.995, 2.512, 3.162, 3.981, 5.012, 6.310,
234 7.943, 10.000, 12.589, 15.849, 19.953, 25.119, 31.623,
235 39.811, 50.119, 63.096, 79.433, 100.000, 125.893, 158.489,
236 199.526, 251.189, 316.228, 398.107, 501.187, 630.958, 794.329,
237 1000.000, 1258.926, 1584.894, 1995.263, 2511.888, 3162.280, 3981.074,
238 5011.875, 6309.578, 7943.287, 10000.010, 12589.260, 15848.940, 19952.640,
239 25118.880, 31622.800};
241 const double tabdEdx[nEntries] = {
242 2443.71800, 1731.65600, 1250.93400, 928.69920, 716.37140, 578.28850,
243 490.83670, 437.33820, 406.58490, 390.95170, 385.29000, 386.12000,
244 391.07730, 398.53930, 407.39420, 416.90860, 426.63010, 436.30240,
245 445.78980, 455.02530, 463.97370, 472.61410, 480.92980, 488.90240,
246 496.51900, 503.77130, 510.65970, 517.19570, 523.39830, 529.29120,
247 534.90670, 540.27590, 545.42880, 550.39890, 555.20800, 559.88820,
248 564.45780, 568.93850, 573.34700, 577.69140, 581.99010, 586.25090,
249 590.47720, 594.68660, 598.86880, 603.03510, 607.18890, 611.33250,
250 615.46810, 619.59740, 623.72150};
256 std::cerr <<
className <<
"::GetStoppingPower:\n";
257 std::cerr <<
" Bg is below the tabulated range.\n";
259 return tabdEdx[0] * 1.e4;
260 }
else if (bg > tabBg[nEntries - 1]) {
261 return tabdEdx[nEntries - 1] * 1.e4;
266 int iUp = nEntries - 1;
268 while (iUp - iLow > 1) {
269 iM = (iUp + iLow) >> 1;
270 if (bg >= tabBg[iM]) {
278 std::cout <<
className <<
"::GetStoppingPower:\n";
279 std::cout <<
" Bg = " << bg <<
"\n";
280 std::cout <<
" Interpolating between " << tabBg[iLow] <<
" and "
281 << tabBg[iUp] <<
"\n";
284 if (
fabs(bg - tabBg[iLow]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
285 return tabdEdx[iLow] * 1.e4;
287 if (
fabs(bg - tabBg[iUp]) < 1.e-6 * (tabBg[iUp] - tabBg[iLow])) {
288 return tabdEdx[iUp] * 1.e4;
292 const double logX0 = log(tabBg[iLow]);
293 const double logX1 = log(tabBg[iUp]);
294 const double logY0 = log(tabdEdx[iLow]);
295 const double logY1 = log(tabdEdx[iUp]);
297 logY0 + (log(bg) - logX0) * (logY1 - logY0) / (logX1 - logX0);
298 return 1.e4 *
exp(dedx);
301bool TrackBichsel::LoadCrossSectionTable(
const std::string filename) {
303 const int nRows = 10000;
304 const int nBlocks = 2;
305 const int nColumns = 5;
307 const int iSwitch = 99999;
310 char* pPath = getenv(
"GARFIELD_HOME");
312 std::cerr <<
className <<
"::LoadCrossSectionTable:\n";
313 std::cerr <<
" Environment variable GARFIELD_HOME is not set.\n";
316 std::string filepath = pPath;
317 filepath = filepath +
"/Data/" + filename;
320 std::ifstream infile;
321 infile.open(filepath.c_str(), std::ios::in);
324 std::cerr <<
className <<
"::LoadCrossSectionTable:\n";
325 std::cerr <<
" Error opening file " << filename <<
".\n";
332 for (
int i = nRows; i--;) cdf[i].resize(nBlocks * nColumns);
335 std::istringstream data;
339 double val[nColumns];
343 while (!infile.eof() && !infile.fail()) {
345 std::getline(infile, line);
347 line.erase(line.begin(),
348 std::find_if(line.begin(), line.end(),
349 not1(std::ptr_fun<int, int>(isspace))));
351 if (line[0] ==
'#' || line[0] ==
'*' || (line[0] ==
'/' && line[1] ==
'/'))
355 data >> dummy1 >> dummy2;
356 for (
int j = 0; j < nColumns; ++j) data >> val[j];
358 if (dummy1 == iSwitch) {
360 if (iBlock >= nBlocks)
break;
364 }
else if (dummy1 != iRow + 1) {
365 std::cerr <<
className <<
"::LoadCrossSectionTable:\n";
366 std::cerr <<
" Error reading file " << filename <<
".\n";
367 std::cerr <<
" Expected entry " << iRow + 1 <<
", got entry " << dummy1
374 std::cerr <<
className <<
"::LoadCrossSectionTable:\n";
375 std::cerr <<
" Table in file is longer than expected.\n";
380 for (
int j = nColumns; j--;) cdf[iRow][nColumns * iBlock + j] = val[j];
385 std::cerr << className <<
"::LoadCrossSectionTable:\n";
386 std::cerr <<
" Error reading file " << filename <<
".\n";
387 infile.close(), cdf.clear();
393 std::cout <<
className <<
"::LoadCrossSectionTable:\n";
394 std::cout <<
" Input file: " << filename << std::endl;
395 std::cout <<
" Successfully loaded cross-section table from file.\n";
401void TrackBichsel::SelectCrossSectionTable() {
403 const int nTables = 10;
404 const double tabBg[nTables] = {0.31623, 1.00000, 3.16228, 10.00000,
405 31.62278, 100.00000, 316.22780, 1000.00000,
406 3162.27800, 10000.00000};
408 bool gotValue =
false;
410 for (
int i = 0; i < nTables - 1; ++i) {
411 double split =
exp(0.5 * (log(tabBg[i]) + log(tabBg[i + 1])));
418 if (!gotValue) iCdf = nTables - 1;
421 std::cout <<
className <<
"::SelectCrossSectionTable:\n";
422 std::cout <<
" Requested value: bg = " << bg <<
"\n";
423 std::cout <<
" Used table: bg = " << tabBg[iCdf] <<
"\n";
DoubleAc cos(const DoubleAc &f)
DoubleAc sqrt(const DoubleAc &f)
DoubleAc sin(const DoubleAc &f)
DoubleAc exp(const DoubleAc &f)
DoubleAc fabs(const DoubleAc &f)
std::string GetName() const
bool GetMedium(const double x, const double y, const double z, Medium *&medium)
double GetStoppingPower()
bool GetCluster(double &xcls, double &ycls, double &zcls, double &tcls, int &n, double &e, double &extra)
double GetClusterDensity()
bool NewTrack(const double x0, const double y0, const double z0, const double t0, const double dx0, const double dy0, const double dz0)
double GetBetaGamma() const