File indexing completed on 2025-08-05 08:18:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "TGeoMaterialInterface.h"
0021 #include "Exception.h"
0022 #include "IO.h"
0023
0024 #include <TGeoMedium.h>
0025 #include <TGeoMaterial.h>
0026 #include <TGeoManager.h>
0027 #include <assert.h>
0028 #include <math.h>
0029
0030
0031 namespace genfit {
0032
0033 double MeanExcEnergy_get(int Z);
0034 double MeanExcEnergy_get(TGeoMaterial*);
0035
0036
0037 bool
0038 TGeoMaterialInterface::initTrack(double posX, double posY, double posZ,
0039 double dirX, double dirY, double dirZ){
0040 #ifdef DEBUG
0041 debugOut << "TGeoMaterialInterface::initTrack. \n";
0042 debugOut << "Pos "; TVector3(posX, posY, posZ).Print();
0043 debugOut << "Dir "; TVector3(dirX, dirY, dirZ).Print();
0044 #endif
0045
0046
0047 bool result = !gGeoManager->IsSameLocation(posX, posY, posZ, kTRUE);
0048
0049 gGeoManager->SetCurrentDirection(dirX, dirY, dirZ);
0050
0051 if (debugLvl_ > 0) {
0052 debugOut << " TGeoMaterialInterface::initTrack at \n";
0053 debugOut << " position: "; TVector3(posX, posY, posZ).Print();
0054 debugOut << " direction: "; TVector3(dirX, dirY, dirZ).Print();
0055 }
0056
0057 return result;
0058 }
0059
0060
0061 Material TGeoMaterialInterface::getMaterialParameters() {
0062
0063 TGeoMaterial* mat = gGeoManager->GetCurrentVolume()->GetMedium()->GetMaterial();
0064 return Material(mat->GetDensity(), mat->GetZ(), mat->GetA(), mat->GetRadLen(), MeanExcEnergy_get(mat));
0065
0066 }
0067
0068
0069 double
0070 TGeoMaterialInterface::findNextBoundary(const RKTrackRep* rep,
0071 const M1x7& stateOrig,
0072 double sMax,
0073 bool varField)
0074 {
0075 const double delta(1.E-2);
0076 const double epsilon(1.E-1);
0077
0078
0079 M1x3 SA;
0080 M1x7 state7, oldState7;
0081 oldState7 = stateOrig;
0082
0083 int stepSign(sMax < 0 ? -1 : 1);
0084
0085 double s = 0;
0086
0087 const unsigned maxIt = 300;
0088 unsigned it = 0;
0089
0090
0091 gGeoManager->FindNextBoundary(fabs(sMax) - s);
0092 double safety = gGeoManager->GetSafeDistance();
0093 double slDist = gGeoManager->GetStep();
0094
0095
0096
0097
0098
0099 if (slDist < safety)
0100 slDist = safety;
0101 double step = slDist;
0102
0103 if (debugLvl_ > 0)
0104 debugOut << " safety = " << safety << "; step, slDist = " << step << "\n";
0105
0106 while (1) {
0107 if (++it > maxIt){
0108 Exception exc("TGeoMaterialInterface::findNextBoundary ==> maximum number of iterations exceeded",__LINE__,__FILE__);
0109 exc.setFatal();
0110 throw exc;
0111 }
0112
0113
0114 if (s + safety > fabs(sMax)) {
0115 if (debugLvl_ > 0)
0116 debugOut << " next boundary is further away than sMax \n";
0117 return stepSign*(s + safety);
0118 }
0119
0120
0121 if (slDist < delta) {
0122 if (debugLvl_ > 0)
0123 debugOut << " very close to the boundary -> return"
0124 << " stepSign*(s + slDist) = "
0125 << stepSign << "*(" << s + slDist << ")\n";
0126 return stepSign*(s + slDist);
0127 }
0128
0129
0130
0131
0132
0133
0134 state7 = stateOrig;
0135 rep->RKPropagate(state7, nullptr, SA, stepSign*(s + step), varField);
0136
0137
0138
0139 double dist2 = (pow(state7[0] - oldState7[0], 2)
0140 + pow(state7[1] - oldState7[1], 2)
0141 + pow(state7[2] - oldState7[2], 2));
0142
0143 double maxDeviation2 = 0.25*(step*step - dist2);
0144
0145 if (step > safety
0146 && maxDeviation2 > epsilon*epsilon) {
0147
0148
0149
0150
0151
0152
0153
0154
0155 step = std::max(step / 2, safety);
0156 } else {
0157 gGeoManager->PushPoint();
0158 bool volChanged = initTrack(state7[0], state7[1], state7[2],
0159 stepSign*state7[3], stepSign*state7[4],
0160 stepSign*state7[5]);
0161
0162 if (volChanged) {
0163 if (debugLvl_ > 0)
0164 debugOut << " volChanged\n";
0165
0166 gGeoManager->PopPoint();
0167
0168
0169
0170
0171
0172 if (step <= safety) {
0173 if (debugLvl_ > 0)
0174 debugOut << " step <= safety, return stepSign*(s + step) = " << stepSign*(s + step) << "\n";
0175 return stepSign*(s + step);
0176 }
0177
0178
0179
0180 step = std::max(step / 2, safety);
0181 } else {
0182
0183 s += step;
0184
0185 oldState7 = state7;
0186 gGeoManager->PopDummy();
0187
0188 gGeoManager->FindNextBoundary(fabs(sMax) - s);
0189 safety = gGeoManager->GetSafeDistance();
0190 slDist = gGeoManager->GetStep();
0191
0192
0193
0194
0195
0196 if (slDist < safety)
0197 slDist = safety;
0198 step = slDist;
0199 if (debugLvl_ > 0)
0200 debugOut << " safety = " << safety << "; step, slDist = " << step << "\n";
0201 }
0202 }
0203 }
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 const int MeanExcEnergy_NELEMENTS = 93;
0215 const double MeanExcEnergy_vals[MeanExcEnergy_NELEMENTS] = {
0216 1.e15, 19.2, 41.8, 40.0, 63.7, 76.0, 78., 82.0,
0217 95.0, 115.0, 137.0, 149.0, 156.0, 166.0, 173.0, 173.0,
0218 180.0, 174.0, 188.0, 190.0, 191.0, 216.0, 233.0, 245.0,
0219 257.0, 272.0, 286.0, 297.0, 311.0, 322.0, 330.0, 334.0,
0220 350.0, 347.0, 348.0, 343.0, 352.0, 363.0, 366.0, 379.0,
0221 393.0, 417.0, 424.0, 428.0, 441.0, 449.0, 470.0, 470.0,
0222 469.0, 488.0, 488.0, 487.0, 485.0, 491.0, 482.0, 488.0,
0223 491.0, 501.0, 523.0, 535.0, 546.0, 560.0, 574.0, 580.0,
0224 591.0, 614.0, 628.0, 650.0, 658.0, 674.0, 684.0, 694.0,
0225 705.0, 718.0, 727.0, 736.0, 746.0, 757.0, 790.0, 790.0,
0226 800.0, 810.0, 823.0, 823.0, 830.0, 825.0, 794.0, 827.0,
0227 826.0, 841.0, 847.0, 878.0, 890.0, };
0228
0229 const double MeanExcEnergy_logs[MeanExcEnergy_NELEMENTS] = {
0230 34.5388, 2.95491, 3.7329, 3.68888, 4.15418, 4.33073, 4.35671, 4.40672,
0231 4.55388, 4.74493, 4.91998, 5.00395, 5.04986, 5.11199, 5.15329, 5.15329,
0232 5.19296, 5.15906, 5.23644, 5.24702, 5.25227, 5.37528, 5.45104, 5.50126,
0233 5.54908, 5.6058, 5.65599, 5.69373, 5.73979, 5.77455, 5.79909, 5.81114,
0234 5.85793, 5.84932, 5.8522, 5.83773, 5.86363, 5.8944, 5.90263, 5.93754,
0235 5.97381, 6.03309, 6.04973, 6.05912, 6.08904, 6.10702, 6.15273, 6.15273,
0236 6.1506, 6.19032, 6.19032, 6.18826, 6.18415, 6.19644, 6.17794, 6.19032,
0237 6.19644, 6.21661, 6.25958, 6.28227, 6.30262, 6.32794, 6.35263, 6.36303,
0238 6.38182, 6.41999, 6.44254, 6.47697, 6.4892, 6.51323, 6.52796, 6.54247,
0239 6.5582, 6.57647, 6.58893, 6.60123, 6.61473, 6.62936, 6.67203, 6.67203,
0240 6.68461, 6.69703, 6.71296, 6.71296, 6.72143, 6.71538, 6.67708, 6.7178,
0241 6.71659, 6.73459, 6.7417, 6.77765, 6.79122, };
0242
0243
0244 double
0245 MeanExcEnergy_get(int Z, bool logs = false) {
0246 assert(Z >= 0 && Z < MeanExcEnergy_NELEMENTS);
0247 if (logs)
0248 return MeanExcEnergy_logs[Z];
0249 else
0250 return MeanExcEnergy_vals[Z];
0251 }
0252
0253
0254 double
0255 MeanExcEnergy_get(TGeoMaterial* mat) {
0256 if (mat->IsMixture()) {
0257
0258
0259 double logMEE = 0.;
0260 double denom = 0.;
0261 TGeoMixture* mix = (TGeoMixture*)mat;
0262 for (int i = 0; i < mix->GetNelements(); ++i) {
0263 int index = int(mix->GetZmixt()[i]);
0264 double weight = mix->GetWmixt()[i] * mix->GetZmixt()[i] / mix->GetAmixt()[i];
0265 logMEE += weight * MeanExcEnergy_get(index, true);
0266 denom += weight;
0267 }
0268 logMEE /= denom;
0269 return exp(logMEE);
0270 }
0271
0272
0273 int index = int(mat->GetZ());
0274 return MeanExcEnergy_get(index, false);
0275 }
0276
0277
0278 }