File indexing completed on 2025-11-08 10:07:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #ifndef G4ParticleHPVector_h
0035 #define G4ParticleHPVector_h 1
0036
0037 #include "G4Exp.hh"
0038 #include "G4InterpolationManager.hh"
0039 #include "G4Log.hh"
0040 #include "G4ParticleHPDataPoint.hh"
0041 #include "G4ParticleHPHash.hh"
0042 #include "G4ParticleHPInterpolator.hh"
0043 #include "G4PhysicsVector.hh"
0044 #include "G4Pow.hh"
0045 #include "G4ios.hh"
0046 #include "Randomize.hh"
0047
0048 #include <cmath>
0049 #include <fstream>
0050 #include <vector>
0051
0052 #if defined WIN32 - VC
0053 # include <float.h>
0054 #endif
0055
0056 class G4ParticleHPVector
0057 {
0058 friend G4ParticleHPVector& operator+(G4ParticleHPVector& left, G4ParticleHPVector& right);
0059
0060 public:
0061 G4ParticleHPVector();
0062
0063 G4ParticleHPVector(G4int n);
0064
0065 ~G4ParticleHPVector();
0066
0067 G4ParticleHPVector& operator=(const G4ParticleHPVector& right);
0068
0069 inline void SetVerbose(G4int ff) { Verbose = ff; }
0070
0071 inline void Times(G4double factor)
0072 {
0073 G4int i;
0074 for (i = 0; i < nEntries; i++) {
0075 theData[i].SetY(theData[i].GetY() * factor);
0076 }
0077 if (theIntegral != nullptr) {
0078 theIntegral[i] *= factor;
0079 }
0080 }
0081
0082 inline void SetPoint(G4int i, const G4ParticleHPDataPoint& it)
0083 {
0084 G4double x = it.GetX();
0085 G4double y = it.GetY();
0086 SetData(i, x, y);
0087 }
0088
0089 inline void SetData(G4int i, G4double x, G4double y)
0090 {
0091
0092 Check(i);
0093 if (y > maxValue) maxValue = y;
0094 theData[i].SetData(x, y);
0095 }
0096 inline void SetX(G4int i, G4double e)
0097 {
0098 Check(i);
0099 theData[i].SetX(e);
0100 }
0101 inline void SetEnergy(G4int i, G4double e)
0102 {
0103 Check(i);
0104 theData[i].SetX(e);
0105 }
0106 inline void SetY(G4int i, G4double x)
0107 {
0108 Check(i);
0109 if (x > maxValue) maxValue = x;
0110 theData[i].SetY(x);
0111 }
0112 inline void SetXsec(G4int i, G4double x)
0113 {
0114 Check(i);
0115 if (x > maxValue) maxValue = x;
0116 theData[i].SetY(x);
0117 }
0118 inline G4double GetEnergy(G4int i) const { return theData[i].GetX(); }
0119 inline G4double GetXsec(G4int i) { return theData[i].GetY(); }
0120 inline G4double GetX(G4int i) const
0121 {
0122 if (i < 0) i = 0;
0123 if (i >= GetVectorLength()) i = GetVectorLength() - 1;
0124 return theData[i].GetX();
0125 }
0126 inline const G4ParticleHPDataPoint& GetPoint(G4int i) const { return theData[i]; }
0127
0128 void Hash()
0129 {
0130 G4int i;
0131 G4double x, y;
0132 for (i = 0; i < nEntries; i++) {
0133 if (0 == (i + 1) % 10) {
0134 x = GetX(i);
0135 y = GetY(i);
0136 theHash.SetData(i, x, y);
0137 }
0138 }
0139 }
0140
0141 void ReHash()
0142 {
0143 theHash.Clear();
0144 Hash();
0145 }
0146
0147 G4double GetXsec(G4double e);
0148
0149 G4int GetEnergyIndex(G4double &e);
0150
0151 G4double GetXsec(G4double e, G4int min)
0152 {
0153 G4int i;
0154 for (i = min; i < nEntries; i++) {
0155 if (theData[i].GetX() > e) break;
0156 }
0157 G4int low = i - 1;
0158 G4int high = i;
0159 if (i == 0) {
0160 low = 0;
0161 high = 1;
0162 }
0163 else if (i == nEntries) {
0164 low = nEntries - 2;
0165 high = nEntries - 1;
0166 }
0167 G4double y;
0168 if (e < theData[nEntries - 1].GetX()) {
0169
0170 if ((theData[high].GetX() - theData[low].GetX()) / theData[high].GetX() < 0.000001) {
0171 y = theData[low].GetY();
0172 }
0173 else {
0174 y = theInt.Interpolate(theManager.GetScheme(high), e, theData[low].GetX(),
0175 theData[high].GetX(), theData[low].GetY(), theData[high].GetY());
0176 }
0177 }
0178 else {
0179 y = theData[nEntries - 1].GetY();
0180 }
0181 return y;
0182 }
0183
0184 inline G4double GetY(G4double x) { return GetXsec(x); }
0185 inline G4int GetVectorLength() const { return nEntries; }
0186
0187 inline G4double GetY(G4int i)
0188 {
0189 if (i < 0) i = 0;
0190 if (i >= GetVectorLength()) i = GetVectorLength() - 1;
0191 return theData[i].GetY();
0192 }
0193
0194 inline G4double GetY(G4int i) const
0195 {
0196 if (i < 0) i = 0;
0197 if (i >= GetVectorLength()) i = GetVectorLength() - 1;
0198 return theData[i].GetY();
0199 }
0200 void Dump();
0201
0202 inline void InitInterpolation(std::istream& aDataFile) { theManager.Init(aDataFile); }
0203
0204 void Init(std::istream& aDataFile, G4int total, G4double ux = 1., G4double uy = 1.)
0205 {
0206 G4double x, y;
0207 for (G4int i = 0; i < total; i++) {
0208 aDataFile >> x >> y;
0209 x *= ux;
0210 y *= uy;
0211 SetData(i, x, y);
0212 if (0 == nEntries % 10) {
0213 theHash.SetData(nEntries - 1, x, y);
0214 }
0215 }
0216 }
0217
0218 void Init(std::istream& aDataFile, G4double ux = 1., G4double uy = 1.)
0219 {
0220 G4int total;
0221 aDataFile >> total;
0222 delete[] theData;
0223 theData = new G4ParticleHPDataPoint[total];
0224 nPoints = total;
0225 nEntries = 0;
0226 theManager.Init(aDataFile);
0227 Init(aDataFile, total, ux, uy);
0228 }
0229
0230 void ThinOut(G4double precision);
0231
0232 inline void SetLabel(G4double aLabel) { label = aLabel; }
0233
0234 inline G4double GetLabel() { return label; }
0235
0236 inline void CleanUp()
0237 {
0238 nEntries = 0;
0239 theManager.CleanUp();
0240 maxValue = -DBL_MAX;
0241 theHash.Clear();
0242
0243 delete[] theIntegral;
0244 theIntegral = nullptr;
0245 }
0246
0247
0248 inline void Merge(G4ParticleHPVector* active, G4ParticleHPVector* passive)
0249 {
0250 CleanUp();
0251 G4int s_tmp = 0, n = 0, m_tmp = 0;
0252 G4ParticleHPVector* tmp;
0253 G4int a = s_tmp, p = n, t;
0254 while (a < active->GetVectorLength()
0255 && p < passive->GetVectorLength())
0256 {
0257 if (active->GetEnergy(a) <= passive->GetEnergy(p)) {
0258 G4double xa = active->GetEnergy(a);
0259 G4double yy = active->GetXsec(a);
0260 SetData(m_tmp, xa, yy);
0261 theManager.AppendScheme(m_tmp, active->GetScheme(a));
0262 m_tmp++;
0263 a++;
0264 G4double xp = passive->GetEnergy(p);
0265
0266
0267
0268 if (!(xa == 0) && std::abs(std::abs(xp - xa) / xa) < 0.001) p++;
0269 }
0270 else {
0271 tmp = active;
0272 t = a;
0273 active = passive;
0274 a = p;
0275 passive = tmp;
0276 p = t;
0277 }
0278 }
0279 while (a != active->GetVectorLength())
0280 {
0281 SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a));
0282 theManager.AppendScheme(m_tmp++, active->GetScheme(a));
0283 a++;
0284 }
0285 while (p != passive->GetVectorLength())
0286 {
0287 if (std::abs(GetEnergy(m_tmp - 1) - passive->GetEnergy(p)) / passive->GetEnergy(p) > 0.001)
0288
0289 {
0290 SetData(m_tmp, passive->GetEnergy(p), passive->GetXsec(p));
0291 theManager.AppendScheme(m_tmp++, active->GetScheme(p));
0292 }
0293 p++;
0294 }
0295 }
0296
0297 void Merge(G4InterpolationScheme aScheme, G4double aValue, G4ParticleHPVector* active,
0298 G4ParticleHPVector* passive);
0299
0300 G4double SampleLin()
0301 {
0302 G4double result;
0303 if (theIntegral == nullptr) IntegrateAndNormalise();
0304 if (GetVectorLength() == 1) {
0305 result = theData[0].GetX();
0306 }
0307 else {
0308 G4int i;
0309 G4double rand = G4UniformRand();
0310
0311
0312
0313
0314
0315
0316
0317
0318 for (i = GetVectorLength() - 1; i >= 0; i--) {
0319 if (rand > theIntegral[i] / theIntegral[GetVectorLength() - 1]) break;
0320 }
0321 if (i != GetVectorLength() - 1) i++;
0322
0323
0324 G4double x1, x2, y1, y2;
0325 y1 = theData[i - 1].GetX();
0326 x1 = theIntegral[i - 1];
0327 y2 = theData[i].GetX();
0328 x2 = theIntegral[i];
0329 if (std::abs((y2 - y1) / y2)
0330 < 0.0000001)
0331 {
0332 y1 = theData[i - 2].GetX();
0333 x1 = theIntegral[i - 2];
0334 }
0335 result = theLin.Lin(rand, x1, x2, y1, y2);
0336 }
0337 return result;
0338 }
0339
0340 G4double Sample();
0341
0342 G4double* Debug() { return theIntegral; }
0343
0344 inline void IntegrateAndNormalise()
0345 {
0346 G4int i;
0347 if (theIntegral != nullptr) return;
0348 theIntegral = new G4double[nEntries];
0349 if (nEntries == 1) {
0350 theIntegral[0] = 1;
0351 return;
0352 }
0353 theIntegral[0] = 0;
0354 G4double sum = 0;
0355 G4double x1 = 0;
0356 G4double x0 = 0;
0357 for (i = 1; i < GetVectorLength(); i++) {
0358 x1 = theData[i].GetX();
0359 x0 = theData[i - 1].GetX();
0360 if (std::abs(x1 - x0) > std::abs(x1 * 0.0000001)) {
0361
0362
0363
0364
0365
0366
0367
0368 G4InterpolationScheme aScheme = theManager.GetScheme(i);
0369 G4double y0 = theData[i - 1].GetY();
0370 G4double y1 = theData[i].GetY();
0371 G4double integ = theInt.GetBinIntegral(aScheme, x0, x1, y0, y1);
0372 #if defined WIN32 - VC
0373 if (!_finite(integ)) {
0374 integ = 0;
0375 }
0376 #elif defined __IBMCPP__
0377 if (isinf(integ) || isnan(integ)) {
0378 integ = 0;
0379 }
0380 #else
0381 if (std::isinf(integ) || std::isnan(integ)) {
0382 integ = 0;
0383 }
0384 #endif
0385 sum += integ;
0386
0387 }
0388 theIntegral[i] = sum;
0389 }
0390 G4double total = theIntegral[GetVectorLength() - 1];
0391 for (i = 1; i < GetVectorLength(); i++) {
0392 theIntegral[i] /= total;
0393 }
0394 }
0395
0396 inline void Integrate()
0397 {
0398 G4int i;
0399 if (nEntries == 1) {
0400 totalIntegral = 0;
0401 return;
0402 }
0403 G4double sum = 0;
0404 for (i = 1; i < GetVectorLength(); i++) {
0405 if (std::abs((theData[i].GetX() - theData[i - 1].GetX()) / theData[i].GetX()) > 0.0000001) {
0406 G4double x1 = theData[i - 1].GetX();
0407 G4double x2 = theData[i].GetX();
0408 G4double y1 = theData[i - 1].GetY();
0409 G4double y2 = theData[i].GetY();
0410 G4InterpolationScheme aScheme = theManager.GetScheme(i);
0411 if (aScheme == LINLIN || aScheme == CLINLIN || aScheme == ULINLIN) {
0412 sum += 0.5 * (y2 + y1) * (x2 - x1);
0413 }
0414 else if (aScheme == LINLOG || aScheme == CLINLOG || aScheme == ULINLOG) {
0415 G4double a = y1;
0416 G4double b = (y2 - y1) / (G4Log(x2) - G4Log(x1));
0417 sum += (a - b) * (x2 - x1) + b * (x2 * G4Log(x2) - x1 * G4Log(x1));
0418 }
0419 else if (aScheme == LOGLIN || aScheme == CLOGLIN || aScheme == ULOGLIN) {
0420 G4double a = G4Log(y1);
0421 G4double b = (G4Log(y2) - G4Log(y1)) / (x2 - x1);
0422 sum += (G4Exp(a) / b) * (G4Exp(b * x2) - G4Exp(b * x1));
0423 }
0424 else if (aScheme == HISTO || aScheme == CHISTO || aScheme == UHISTO) {
0425 sum += y1 * (x2 - x1);
0426 }
0427 else if (aScheme == LOGLOG || aScheme == CLOGLOG || aScheme == ULOGLOG) {
0428 G4double a = G4Log(y1);
0429 G4double b = (G4Log(y2) - G4Log(y1)) / (G4Log(x2) - G4Log(x1));
0430 sum +=
0431 (G4Exp(a) / (b + 1))
0432 * (G4Pow::GetInstance()->powA(x2, b + 1) - G4Pow::GetInstance()->powA(x1, b + 1));
0433 }
0434 else {
0435 throw G4HadronicException(
0436 __FILE__, __LINE__, "Unknown interpolation scheme in G4ParticleHPVector::Integrate");
0437 }
0438 }
0439 }
0440 totalIntegral = sum;
0441 }
0442
0443 inline G4double GetIntegral()
0444 {
0445 if (totalIntegral < -0.5) Integrate();
0446 return totalIntegral;
0447 }
0448
0449 inline void SetInterpolationManager(const G4InterpolationManager& aManager)
0450 {
0451 theManager = aManager;
0452 }
0453
0454 inline const G4InterpolationManager& GetInterpolationManager() const { return theManager; }
0455
0456 inline void SetInterpolationManager(G4InterpolationManager& aMan) { theManager = aMan; }
0457
0458 inline void SetScheme(G4int aPoint, const G4InterpolationScheme& aScheme)
0459 {
0460 theManager.AppendScheme(aPoint, aScheme);
0461 }
0462
0463 inline G4InterpolationScheme GetScheme(G4int anIndex) { return theManager.GetScheme(anIndex); }
0464
0465 G4double GetMeanX()
0466 {
0467 G4double result;
0468 G4double running = 0;
0469 G4double weighted = 0;
0470 for (G4int i = 1; i < nEntries; i++) {
0471 running +=
0472 theInt.GetBinIntegral(theManager.GetScheme(i - 1), theData[i - 1].GetX(),
0473 theData[i].GetX(), theData[i - 1].GetY(), theData[i].GetY());
0474 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i - 1),
0475 theData[i - 1].GetX(), theData[i].GetX(),
0476 theData[i - 1].GetY(), theData[i].GetY());
0477 }
0478 result = weighted / running;
0479 return result;
0480 }
0481
0482
0483 G4double GetMaxY(G4double emin, G4double emax);
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497 std::vector<G4double> GetBlocked() { return theBlocked; }
0498 std::vector<G4double> GetBuffered() { return theBuffered; }
0499
0500
0501
0502
0503 G4double Get15percentBorder();
0504 G4double Get50percentBorder();
0505
0506 private:
0507 void Check(G4int i);
0508
0509 G4bool IsBlocked(G4double aX);
0510
0511 private:
0512 G4ParticleHPInterpolator theLin;
0513
0514 private:
0515 G4double totalIntegral;
0516
0517 G4ParticleHPDataPoint* theData;
0518 G4InterpolationManager theManager;
0519 G4double* theIntegral;
0520 G4int nEntries;
0521 G4int nPoints;
0522 G4double label;
0523
0524 G4ParticleHPInterpolator theInt;
0525 G4int Verbose;
0526
0527 G4int isFreed;
0528
0529 G4ParticleHPHash theHash;
0530 G4double maxValue;
0531
0532 std::vector<G4double> theBlocked;
0533 std::vector<G4double> theBuffered;
0534 G4double the15percentBorderCash;
0535 G4double the50percentBorderCash;
0536 };
0537
0538 #endif