Geant4-11
G4VXTRenergyLoss.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// History:
27// 2001-2002 R&D by V.Grichine
28// 19.06.03 V. Grichine, modifications in BuildTable for the integration
29// in respect of angle: range is increased, accuracy is
30// improved
31// 28.07.05, P.Gumplinger add G4ProcessType to constructor
32// 28.09.07, V.Ivanchenko general cleanup without change of algorithms
33//
34
35#include "G4VXTRenergyLoss.hh"
36
37#include "G4AffineTransform.hh"
38#include "G4DynamicParticle.hh"
39#include "G4EmProcessSubType.hh"
40#include "G4Integrator.hh"
41#include "G4MaterialTable.hh"
42#include "G4ParticleMomentum.hh"
46#include "G4PhysicsLogVector.hh"
47#include "G4RotationMatrix.hh"
48#include "G4SandiaTable.hh"
49#include "G4SystemOfUnits.hh"
50#include "G4ThreeVector.hh"
51#include "G4Timer.hh"
52#include "G4VDiscreteProcess.hh"
53#include "G4VParticleChange.hh"
54#include "G4VSolid.hh"
56
58// Constructor, destructor
60 G4Material* foilMat, G4Material* gasMat,
62 const G4String& processName,
63 G4ProcessType type)
64 : G4VDiscreteProcess(processName, type)
65 , fGammaCutInKineticEnergy(nullptr)
66 , fAngleDistrTable(nullptr)
67 , fEnergyDistrTable(nullptr)
68 , fAngleForEnergyTable(nullptr)
69 , fPlatePhotoAbsCof(nullptr)
70 , fGasPhotoAbsCof(nullptr)
71 , fGammaTkinCut(0.0)
72{
73 verboseLevel = 1;
74 secID = G4PhysicsModelCatalog::GetModelID("model_XTRenergyLoss");
76
77 fPtrGamma = nullptr;
80 fAlphaPlate = 100.;
81 fAlphaGas = 40.;
82
83 fTheMinEnergyTR = CLHEP::keV * 1.; // 1.; //
84 fTheMaxEnergyTR = CLHEP::keV * 100.; // 40.; //
85
86 fTheMinAngle = 1.e-8; //
87 fTheMaxAngle = 4.e-4;
88
89 fTotBin = 50; // number of bins in log scale
90 fBinTR = 100; // number of bins in TR vectors
91
92 // min/max angle2 in log-vectors
93
94 fMinThetaTR = 3.0e-9;
95 fMaxThetaTR = 1.0e-4;
96
97
98 // Proton energy vector initialization
101
104
105 fEnvelope = anEnvelope;
106
107 fPlateNumber = n;
108 if(verboseLevel > 0)
109 G4cout << "### G4VXTRenergyLoss: the number of TR radiator plates = "
110 << fPlateNumber << G4endl;
111 if(fPlateNumber == 0)
112 {
113 G4Exception("G4VXTRenergyLoss::G4VXTRenergyLoss()", "VXTRELoss01",
114 FatalException, "No plates in X-ray TR radiator");
115 }
116 // default is XTR dEdx, not flux after radiator
117 fExitFlux = false;
118 // default angle distribution according numerical integration
119 fFastAngle = false; // no angle according sum of delta-functions by default
120 fAngleRadDistr = true;
121 fCompton = false;
122
124
125 // Mean thicknesses of plates and gas gaps
126 fPlateThick = a;
127 fGasThick = b;
129 if(verboseLevel > 0)
130 G4cout << "total radiator thickness = " << fTotalDist / cm << " cm"
131 << G4endl;
132
133 // index of plate material
134 fMatIndex1 = foilMat->GetIndex();
135 if(verboseLevel > 0)
136 G4cout << "plate material = " << foilMat->GetName() << G4endl;
137
138 // index of gas material
139 fMatIndex2 = gasMat->GetIndex();
140 if(verboseLevel > 0)
141 G4cout << "gas material = " << gasMat->GetName() << G4endl;
142
143 // plasma energy squared for plate material
145 if(verboseLevel > 0)
146 G4cout << "plate plasma energy = " << std::sqrt(fSigma1) / eV << " eV"
147 << G4endl;
148
149 // plasma energy squared for gas material
151 if(verboseLevel > 0)
152 G4cout << "gas plasma energy = " << std::sqrt(fSigma2) / eV << " eV"
153 << G4endl;
154
155 // Compute cofs for preparation of linear photo absorption
158
160}
161
164{
165 delete fProtonEnergyVector;
166 delete fXTREnergyVector;
168 {
170 delete fEnergyDistrTable;
171 }
173 {
175 delete fAngleDistrTable;
176 }
178 {
181 }
182}
183
184void G4VXTRenergyLoss::ProcessDescription(std::ostream& out) const
185{
186 out << "Base class for 'fast' parameterisation model describing X-ray "
187 "transition\n"
188 "radiation. Angular distribution is very rough.\n";
189}
190
192// Returns condition for application of the model depending on particle type
194{
195 return (particle.GetPDGCharge() != 0.0);
196}
197
199// Calculate step size for XTR process inside raaditor
202{
203 G4int iTkin, iPlace;
204 G4double lambda, sigma, kinEnergy, mass, gamma;
205 G4double charge, chargeSq, massRatio, TkinScaled;
206 G4double E1, E2, W, W1, W2;
207
209
210 if(aTrack.GetVolume()->GetLogicalVolume() != fEnvelope)
211 lambda = DBL_MAX;
212 else
213 {
214 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
215 kinEnergy = aParticle->GetKineticEnergy();
216 mass = aParticle->GetDefinition()->GetPDGMass();
217 gamma = 1.0 + kinEnergy / mass;
218 if(verboseLevel > 1)
219 {
220 G4cout << " gamma = " << gamma << "; fGamma = " << fGamma << G4endl;
221 }
222
223 if(std::fabs(gamma - fGamma) < 0.05 * gamma)
224 lambda = fLambda;
225 else
226 {
227 charge = aParticle->GetDefinition()->GetPDGCharge();
228 chargeSq = charge * charge;
229 massRatio = proton_mass_c2 / mass;
230 TkinScaled = kinEnergy * massRatio;
231
232 for(iTkin = 0; iTkin < fTotBin; ++iTkin)
233 {
234 if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
235 break;
236 }
237 iPlace = iTkin - 1;
238
239 if(iTkin == 0)
240 lambda = DBL_MAX; // Tkin is too small, neglect of TR photon generation
241 else // general case: Tkin between two vectors of the material
242 {
243 if(iTkin == fTotBin)
244 {
245 sigma = (*(*fEnergyDistrTable)(iPlace))(0) * chargeSq;
246 }
247 else
248 {
249 E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1);
251 W = 1.0 / (E2 - E1);
252 W1 = (E2 - TkinScaled) * W;
253 W2 = (TkinScaled - E1) * W;
254 sigma = ((*(*fEnergyDistrTable)(iPlace))(0) * W1 +
255 (*(*fEnergyDistrTable)(iPlace + 1))(0) * W2) *
256 chargeSq;
257 }
258 if(sigma < DBL_MIN)
259 lambda = DBL_MAX;
260 else
261 lambda = 1. / sigma;
262 fLambda = lambda;
263 fGamma = gamma;
264 if(verboseLevel > 1)
265 {
266 G4cout << " lambda = " << lambda / mm << " mm" << G4endl;
267 }
268 }
269 }
270 }
271 return lambda;
272}
273
275// Interface for build table from physics list
277{
278 if(pd.GetPDGCharge() == 0.)
279 {
280 G4Exception("G4VXTRenergyLoss::BuildPhysicsTable", "Notification",
281 JustWarning, "XTR initialisation for neutral particle ?!");
282 }
284
286 {
287 if(verboseLevel > 0)
288 {
289 G4cout
290 << "Build angle for energy distribution according the current radiator"
291 << G4endl;
292 }
294 }
295}
296
298// Build integral energy distribution of XTR photons
300{
301 G4int iTkin, iTR, iPlace;
302 G4double radiatorCof = 1.0; // for tuning of XTR yield
303 G4double energySum = 0.0;
304
308
309 fGammaTkinCut = 0.0;
310
311 // setting of min/max TR energies
314 else
316
319 else
321
323 integral;
324
325 G4cout.precision(4);
326 G4Timer timer;
327 timer.Start();
328
329 if(verboseLevel > 0)
330 {
331 G4cout << G4endl;
332 G4cout << "Lorentz Factor"
333 << "\t"
334 << "XTR photon number" << G4endl;
335 G4cout << G4endl;
336 }
337 for(iTkin = 0; iTkin < fTotBin; ++iTkin) // Lorentz factor loop
338 {
339 G4PhysicsLogVector* energyVector =
341
342 fGamma =
344
345 fMaxThetaTR = 25. * 2500.0 / (fGamma * fGamma); // theta^2
346
349 else if(fMaxThetaTR < fTheMinAngle)
351
352 energySum = 0.0;
353
354 energyVector->PutValue(fBinTR - 1, energySum);
355
356 for(iTR = fBinTR - 2; iTR >= 0; --iTR)
357 {
358 // Legendre96 or Legendre10
359
360 energySum += radiatorCof * fCofTR *
361
362 // integral.Legendre10(this, &G4VXTRenergyLoss::SpectralXTRdEdx,
363
364 integral.Legendre96(this, &G4VXTRenergyLoss::SpectralXTRdEdx,
365
366 energyVector->GetLowEdgeEnergy(iTR),
367 energyVector->GetLowEdgeEnergy(iTR + 1));
368
369 energyVector->PutValue(iTR, energySum / fTotalDist);
370 }
371 iPlace = iTkin;
372 fEnergyDistrTable->insertAt(iPlace, energyVector);
373
374 if(verboseLevel > 0)
375 {
376 G4cout << fGamma << "\t" << energySum << G4endl;
377 }
378 }
379 timer.Stop();
380 G4cout.precision(6);
381 if(verboseLevel > 0)
382 {
383 G4cout << G4endl;
384 G4cout << "total time for build X-ray TR energy loss tables = "
385 << timer.GetUserElapsed() << " s" << G4endl;
386 }
387 fGamma = 0.;
388 return;
389}
390
392// Bank of angle distributions for given energies (slow!)
393
395{
396
397 if( ( this->GetProcessName() == "TranspRegXTRadiator" ||
398 this->GetProcessName() == "TranspRegXTRmodel" ||
399 this->GetProcessName() == "RegularXTRadiator" ||
400 this->GetProcessName() == "RegularXTRmodel" ) && fFastAngle ) // ffastAngle=true!
401 {
402 BuildAngleTable(); // by sum of delta-functions
403 return;
404 }
405 G4int i, iTkin, iTR;
406 G4double angleSum = 0.0;
407
408 fGammaTkinCut = 0.0;
409
410 // setting of min/max TR energies
413 else
415
418 else
420
421 G4PhysicsLogVector* energyVector =
423
425 integral;
426
427 G4cout.precision(4);
428 G4Timer timer;
429 timer.Start();
430
431 for(iTkin = 0; iTkin < fTotBin; ++iTkin) // Lorentz factor loop
432 {
433 fGamma =
435
438 else if(fMaxThetaTR < fTheMinAngle)
440
442
443 for(iTR = 0; iTR < fBinTR; ++iTR)
444 {
445 angleSum = 0.0;
446 fEnergy = energyVector->GetLowEdgeEnergy(iTR);
447
448 // log-vector to increase number of thin bins for small angles
450
451
452
453 angleVector->PutValue(fBinTR - 1, angleSum);
454
455 for(i = fBinTR - 2; i >= 0; --i)
456 {
457 // Legendre96 or Legendre10
458
459 angleSum +=
460 integral.Legendre10(this, &G4VXTRenergyLoss::SpectralAngleXTRdEdx,
461 angleVector->GetLowEdgeEnergy(i),
462 angleVector->GetLowEdgeEnergy(i + 1));
463
464 angleVector->PutValue(i, angleSum);
465 }
466 fAngleForEnergyTable->insertAt(iTR, angleVector);
467 }
469 }
470 timer.Stop();
471 G4cout.precision(6);
472 if(verboseLevel > 0)
473 {
474 G4cout << G4endl;
475 G4cout << "total time for build X-ray TR angle for energy loss tables = "
476 << timer.GetUserElapsed() << " s" << G4endl;
477 }
478 fGamma = 0.;
479 delete energyVector;
480}
481
483// Build XTR angular distribution at given energy based on the model
484// of transparent regular radiator
486{
487 G4int iTkin, iTR;
489
490 fGammaTkinCut = 0.0;
491
492 // setting of min/max TR energies
495 else
497
500 else
502
503 G4cout.precision(4);
504 G4Timer timer;
505 timer.Start();
506 if(verboseLevel > 0)
507 {
508 G4cout << G4endl << "Lorentz Factor" << "\t"
509 << "XTR photon number" << G4endl << G4endl;
510 }
511 for(iTkin = 0; iTkin < fTotBin; ++iTkin) // Lorentz factor loop
512 {
513 fGamma =
515
516 // fMaxThetaTR = 25. * 2500.0 / (fGamma * fGamma); // theta^2
517
520 else
521 {
524 }
525
527
528 for(iTR = 0; iTR < fBinTR; ++iTR)
529 {
531
533
534 fAngleForEnergyTable->insertAt(iTR, angleVector);
535 }
537 }
538 timer.Stop();
539 G4cout.precision(6);
540 if(verboseLevel > 0)
541 {
542 G4cout << G4endl;
543 G4cout << "total time for build XTR angle for given energy tables = "
544 << timer.GetUserElapsed() << " s" << G4endl;
545 }
546 fGamma = 0.;
547
548 return;
549}
550
552// Vector of angles and angle integral distributions
554{
555 G4double theta = 0., result, tmp = 0., cof1, cof2, cofMin, cofPHC,
556 angleSum = 0.;
557 G4int iTheta, k, kMin;
558
559 G4PhysicsFreeVector* angleVector = new G4PhysicsFreeVector(n);
560
561 cofPHC = 4. * pi * hbarc;
562 tmp = (fSigma1 - fSigma2) / cofPHC / energy;
563 cof1 = fPlateThick * tmp;
564 cof2 = fGasThick * tmp;
565
566 cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
567 cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
568 cofMin /= cofPHC;
569
570 kMin = G4int(cofMin);
571 if(cofMin > kMin)
572 kMin++;
573
574 if(verboseLevel > 2)
575 {
576 G4cout << "n-1 = " << n - 1
577 << "; theta = " << std::sqrt(fMaxThetaTR) * fGamma
578 << "; tmp = " << 0. << "; angleSum = " << angleSum << G4endl;
579 }
580
581 for(iTheta = n - 1; iTheta >= 1; --iTheta)
582 {
583 k = iTheta - 1 + kMin;
584 tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
585 result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
586 tmp = std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
587
588 if(k == kMin && kMin == G4int(cofMin))
589 {
590 // angleSum += 0.5 * tmp;
591 angleSum += tmp; // ATLAS TB
592 }
593 else if(iTheta == n - 1)
594 ;
595 else
596 {
597 angleSum += tmp;
598 }
599 theta = std::abs(k - cofMin) * cofPHC / energy / (fPlateThick + fGasThick);
600
601 if(verboseLevel > 2)
602 {
603 G4cout << "iTheta = " << iTheta << "; k = " << k
604 << "; theta = " << std::sqrt(theta) * fGamma << "; tmp = " << tmp
605 << "; angleSum = " << angleSum << G4endl;
606 }
607 angleVector->PutValue(iTheta, theta, angleSum);
608 }
609 if(theta > 0.)
610 {
611 // angleSum += 0.5 * tmp;
612 angleSum += 0.; // ATLAS TB
613 theta = 0.;
614 }
615 if(verboseLevel > 2)
616 {
617 G4cout << "iTheta = " << iTheta << "; theta = " << std::sqrt(theta) * fGamma
618 << "; tmp = " << tmp << "; angleSum = " << angleSum << G4endl;
619 }
620 angleVector->PutValue(iTheta, theta, angleSum);
621
622 return angleVector;
623}
624
626// Build XTR angular distribution based on the model of transparent regular
627// radiator
629{
630 G4int iTkin, iTR, iPlace;
631 G4double radiatorCof = 1.0; // for tuning of XTR yield
632 G4double angleSum;
634
635 fGammaTkinCut = 0.0;
636
637 // setting of min/max TR energies
640 else
642
645 else
647
648 G4cout.precision(4);
649 G4Timer timer;
650 timer.Start();
651 if(verboseLevel > 0)
652 {
653 G4cout << G4endl;
654 G4cout << "Lorentz Factor"
655 << "\t"
656 << "XTR photon number" << G4endl;
657 G4cout << G4endl;
658 }
659 for(iTkin = 0; iTkin < fTotBin; ++iTkin) // Lorentz factor loop
660 {
661 fGamma =
663
664 // fMaxThetaTR = 25.0 / (fGamma * fGamma); // theta^2
665 // fMaxThetaTR = 1.e-4; // theta^2
666
669 else
670 {
673 }
674 G4PhysicsLinearVector* angleVector =
675 // G4PhysicsLogVector* angleVector =
677 // new G4PhysicsLogVector(1.e-8, fMaxThetaTR, fBinTR);
678
679 angleSum = 0.0;
680
682 integral;
683
684 angleVector->PutValue(fBinTR - 1, angleSum);
685
686 for(iTR = fBinTR - 2; iTR >= 0; --iTR)
687 {
688 angleSum += radiatorCof * fCofTR *
689 integral.Legendre96(this, &G4VXTRenergyLoss::AngleXTRdEdx,
690 angleVector->GetLowEdgeEnergy(iTR),
691 angleVector->GetLowEdgeEnergy(iTR + 1));
692
693 angleVector->PutValue(iTR, angleSum);
694 }
695 if(verboseLevel > 1)
696 {
697 G4cout << fGamma << "\t" << angleSum << G4endl;
698 }
699 iPlace = iTkin;
700 fAngleDistrTable->insertAt(iPlace, angleVector);
701 }
702 timer.Stop();
703 G4cout.precision(6);
704 if(verboseLevel > 0)
705 {
706 G4cout << G4endl;
707 G4cout << "total time for build X-ray TR angle tables = "
708 << timer.GetUserElapsed() << " s" << G4endl;
709 }
710 fGamma = 0.;
711
712 return;
713}
714
716// The main function which is responsible for the treatment of a particle
717// passage through G4Envelope with discrete generation of G4Gamma
719 const G4Step& aStep)
720{
721 G4int iTkin;
722 G4double energyTR, theta, theta2, phi, dirX, dirY, dirZ;
723
725
726 if(verboseLevel > 1)
727 {
728 G4cout << "Start of G4VXTRenergyLoss::PostStepDoIt " << G4endl;
729 G4cout << "name of current material = "
730 << aTrack.GetVolume()->GetLogicalVolume()->GetMaterial()->GetName()
731 << G4endl;
732 }
733 if(aTrack.GetVolume()->GetLogicalVolume() != fEnvelope)
734 {
735 if(verboseLevel > 0)
736 {
737 G4cout << "Go out from G4VXTRenergyLoss::PostStepDoIt: wrong volume "
738 << G4endl;
739 }
740 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
741 }
742 else
743 {
744 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
745 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
746
747 // Now we are ready to Generate one TR photon
748 G4double kinEnergy = aParticle->GetKineticEnergy();
749 G4double mass = aParticle->GetDefinition()->GetPDGMass();
750 G4double gamma = 1.0 + kinEnergy / mass;
751
752 if(verboseLevel > 1)
753 {
754 G4cout << "gamma = " << gamma << G4endl;
755 }
756 G4double massRatio = proton_mass_c2 / mass;
757 G4double TkinScaled = kinEnergy * massRatio;
758 G4ThreeVector position = pPostStepPoint->GetPosition();
759 G4ParticleMomentum direction = aParticle->GetMomentumDirection();
760 G4double startTime = pPostStepPoint->GetGlobalTime();
761
762 for(iTkin = 0; iTkin < fTotBin; ++iTkin)
763 {
764 if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
765 break;
766 }
767
768 if(iTkin == 0) // Tkin is too small, neglect of TR photon generation
769 {
770 if(verboseLevel > 0)
771 {
772 G4cout << "Go out from G4VXTRenergyLoss::PostStepDoIt:iTkin = " << iTkin
773 << G4endl;
774 }
775 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
776 }
777 else // general case: Tkin between two vectors of the material
778 {
780
781 energyTR = GetXTRrandomEnergy(TkinScaled, iTkin);
782
783 if(verboseLevel > 1)
784 {
785 G4cout << "energyTR = " << energyTR / keV << " keV" << G4endl;
786 }
788 {
789 theta2 = GetRandomAngle(energyTR, iTkin);
790 if(theta2 > 0.)
791 theta = std::sqrt(theta2);
792 else
793 theta = 0.;
794 }
795 else
796 theta = std::fabs(G4RandGauss::shoot(0.0, pi / gamma));
797
798 if(theta >= 0.1)
799 theta = 0.1;
800
801 phi = twopi * G4UniformRand();
802
803 dirX = std::sin(theta) * std::cos(phi);
804 dirY = std::sin(theta) * std::sin(phi);
805 dirZ = std::cos(theta);
806
807 G4ThreeVector directionTR(dirX, dirY, dirZ);
808 directionTR.rotateUz(direction);
809 directionTR.unit();
810
811 G4DynamicParticle* aPhotonTR =
812 new G4DynamicParticle(G4Gamma::Gamma(), directionTR, energyTR);
813
814 // A XTR photon is set on the particle track inside the radiator
815 // and is moved to the G4Envelope surface for standard X-ray TR models
816 // only. The case of fExitFlux=true
817
818 if(fExitFlux)
819 {
820 const G4RotationMatrix* rotM =
821 pPostStepPoint->GetTouchable()->GetRotation();
822 G4ThreeVector transl = pPostStepPoint->GetTouchable()->GetTranslation();
824 transform.Invert();
825 G4ThreeVector localP = transform.TransformPoint(position);
826 G4ThreeVector localV = transform.TransformAxis(directionTR);
827
828 G4double distance =
829 fEnvelope->GetSolid()->DistanceToOut(localP, localV);
830 if(verboseLevel > 1)
831 {
832 G4cout << "distance to exit = " << distance / mm << " mm" << G4endl;
833 }
834 position += distance * directionTR;
835 startTime += distance / c_light;
836 }
837 G4Track* aSecondaryTrack = new G4Track(aPhotonTR, startTime, position);
838 aSecondaryTrack->SetTouchableHandle(
840 aSecondaryTrack->SetParentID(aTrack.GetTrackID());
841
842 fParticleChange.AddSecondary(aSecondaryTrack);
844 }
845 }
846 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
847}
848
850// This function returns the spectral and angle density of TR quanta
851// in X-ray energy region generated forward when a relativistic
852// charged particle crosses interface between two materials.
853// The high energy small theta approximation is applied.
854// (matter1 -> matter2, or 2->1)
855// varAngle =2* (1 - std::cos(theta)) or approximately = theta*theta
857 G4double varAngle)
858{
859 G4complex Z1 = GetPlateComplexFZ(energy, gamma, varAngle);
860 G4complex Z2 = GetGasComplexFZ(energy, gamma, varAngle);
861
862 G4complex zOut = (Z1 - Z2) * (Z1 - Z2) * (varAngle * energy / hbarc / hbarc);
863 return zOut;
864}
865
867// For photon energy distribution tables. Integrate first over angle
869{
870 G4double result = GetStackFactor(fEnergy, fGamma, varAngle);
871 if(result < 0.0)
872 result = 0.0;
873 return result;
874}
875
877// For second integration over energy
879{
880 G4int i;
881 static constexpr G4int iMax = 8;
882 G4double angleSum = 0.0;
883
884 G4double lim[iMax] = { 0.0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 };
885
886 for(i = 0; i < iMax; ++i)
887 lim[i] *= fMaxThetaTR;
888
890 integral;
891
892 fEnergy = energy;
893 {
894 for(i = 0; i < iMax - 1; ++i)
895 {
896 angleSum += integral.Legendre96(
897 this, &G4VXTRenergyLoss::SpectralAngleXTRdEdx, lim[i], lim[i + 1]);
898 }
899 }
900 return angleSum;
901}
902
904// for photon angle distribution tables
906{
908 if(result < 0)
909 result = 0.0;
910 return result;
911}
912
914// The XTR angular distribution based on transparent regular radiator
916{
917 G4double result;
918 G4double sum = 0., tmp1, tmp2, tmp = 0., cof1, cof2, cofMin, cofPHC, energy1,
919 energy2;
920 G4int k, kMax, kMin, i;
921
922 cofPHC = twopi * hbarc;
923
924 cof1 = (fPlateThick + fGasThick) * (1. / fGamma / fGamma + varAngle);
926
927 cofMin = std::sqrt(cof1 * cof2);
928 cofMin /= cofPHC;
929
930 kMin = G4int(cofMin);
931 if(cofMin > kMin)
932 kMin++;
933
934 kMax = kMin + 9;
935
936 for(k = kMin; k <= kMax; ++k)
937 {
938 tmp1 = cofPHC * k;
939 tmp2 = std::sqrt(tmp1 * tmp1 - cof1 * cof2);
940 energy1 = (tmp1 + tmp2) / cof1;
941 energy2 = (tmp1 - tmp2) / cof1;
942
943 for(i = 0; i < 2; ++i)
944 {
945 if(i == 0)
946 {
947 if(energy1 > fTheMaxEnergyTR || energy1 < fTheMinEnergyTR)
948 continue;
949
950 tmp1 =
951 (energy1 * energy1 * (1. / fGamma / fGamma + varAngle) + fSigma1) *
952 fPlateThick / (4 * hbarc * energy1);
953 tmp2 = std::sin(tmp1);
954 tmp = energy1 * tmp2 * tmp2;
955 tmp2 = fPlateThick / (4. * tmp1);
956 tmp1 =
957 hbarc * energy1 /
958 (energy1 * energy1 * (1. / fGamma / fGamma + varAngle) + fSigma2);
959 tmp *= (tmp1 - tmp2) * (tmp1 - tmp2);
960 tmp1 = cof1 / (4. * hbarc) - cof2 / (4. * hbarc * energy1 * energy1);
961 tmp2 = std::abs(tmp1);
962
963 if(tmp2 > 0.)
964 tmp /= tmp2;
965 else
966 continue;
967 }
968 else
969 {
970 if(energy2 > fTheMaxEnergyTR || energy2 < fTheMinEnergyTR)
971 continue;
972
973 tmp1 =
974 (energy2 * energy2 * (1. / fGamma / fGamma + varAngle) + fSigma1) *
975 fPlateThick / (4. * hbarc * energy2);
976 tmp2 = std::sin(tmp1);
977 tmp = energy2 * tmp2 * tmp2;
978 tmp2 = fPlateThick / (4. * tmp1);
979 tmp1 =
980 hbarc * energy2 /
981 (energy2 * energy2 * (1. / fGamma / fGamma + varAngle) + fSigma2);
982 tmp *= (tmp1 - tmp2) * (tmp1 - tmp2);
983 tmp1 = cof1 / (4. * hbarc) - cof2 / (4. * hbarc * energy2 * energy2);
984 tmp2 = std::abs(tmp1);
985
986 if(tmp2 > 0.)
987 tmp /= tmp2;
988 else
989 continue;
990 }
991 sum += tmp;
992 }
993 }
994 result = 4. * pi * fPlateNumber * sum * varAngle;
995 result /= hbarc * hbarc;
996
997 return result;
998}
999
1001// Calculates formation zone for plates. Omega is energy !!!
1003 G4double varAngle)
1004{
1005 G4double cof, lambda;
1006 lambda = 1.0 / gamma / gamma + varAngle + fSigma1 / omega / omega;
1007 cof = 2.0 * hbarc / omega / lambda;
1008 return cof;
1009}
1010
1012// Calculates complex formation zone for plates. Omega is energy !!!
1014 G4double varAngle)
1015{
1016 G4double cof, length, delta, real_v, image_v;
1017
1018 length = 0.5 * GetPlateFormationZone(omega, gamma, varAngle);
1019 delta = length * GetPlateLinearPhotoAbs(omega);
1020 cof = 1.0 / (1.0 + delta * delta);
1021
1022 real_v = length * cof;
1023 image_v = real_v * delta;
1024
1025 G4complex zone(real_v, image_v);
1026 return zone;
1027}
1028
1030// Computes matrix of Sandia photo absorption cross section coefficients for
1031// plate material
1033{
1034 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
1035 const G4Material* mat = (*theMaterialTable)[fMatIndex1];
1037
1038 return;
1039}
1040
1042// Returns the value of linear photo absorption coefficient (in reciprocal
1043// length) for plate for given energy of X-ray photon omega
1045{
1046 G4double omega2, omega3, omega4;
1047
1048 omega2 = omega * omega;
1049 omega3 = omega2 * omega;
1050 omega4 = omega2 * omega2;
1051
1052 const G4double* SandiaCof = fPlatePhotoAbsCof->GetSandiaCofForMaterial(omega);
1053 G4double cross = SandiaCof[0] / omega + SandiaCof[1] / omega2 +
1054 SandiaCof[2] / omega3 + SandiaCof[3] / omega4;
1055 return cross;
1056}
1057
1059// Calculates formation zone for gas. Omega is energy !!!
1061 G4double varAngle)
1062{
1063 G4double cof, lambda;
1064 lambda = 1.0 / gamma / gamma + varAngle + fSigma2 / omega / omega;
1065 cof = 2.0 * hbarc / omega / lambda;
1066 return cof;
1067}
1068
1070// Calculates complex formation zone for gas gaps. Omega is energy !!!
1072 G4double varAngle)
1073{
1074 G4double cof, length, delta, real_v, image_v;
1075
1076 length = 0.5 * GetGasFormationZone(omega, gamma, varAngle);
1077 delta = length * GetGasLinearPhotoAbs(omega);
1078 cof = 1.0 / (1.0 + delta * delta);
1079
1080 real_v = length * cof;
1081 image_v = real_v * delta;
1082
1083 G4complex zone(real_v, image_v);
1084 return zone;
1085}
1086
1088// Computes matrix of Sandia photo absorption cross section coefficients for
1089// gas material
1091{
1092 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
1093 const G4Material* mat = (*theMaterialTable)[fMatIndex2];
1095 return;
1096}
1097
1099// Returns the value of linear photo absorption coefficient (in reciprocal
1100// length) for gas
1102{
1103 G4double omega2, omega3, omega4;
1104
1105 omega2 = omega * omega;
1106 omega3 = omega2 * omega;
1107 omega4 = omega2 * omega2;
1108
1109 const G4double* SandiaCof = fGasPhotoAbsCof->GetSandiaCofForMaterial(omega);
1110 G4double cross = SandiaCof[0] / omega + SandiaCof[1] / omega2 +
1111 SandiaCof[2] / omega3 + SandiaCof[3] / omega4;
1112 return cross;
1113}
1114
1116// Calculates the product of linear cof by formation zone for plate.
1117// Omega is energy !!!
1119 G4double varAngle)
1120{
1121 return GetPlateFormationZone(omega, gamma, varAngle) *
1123}
1125// Calculates the product of linear cof by formation zone for plate.
1126// G4cout and output in file in some energy range.
1128{
1129 std::ofstream outPlate("plateZmu.dat", std::ios::out);
1130 outPlate.setf(std::ios::scientific, std::ios::floatfield);
1131
1132 G4int i;
1133 G4double omega, varAngle, gamma;
1134 gamma = 10000.;
1135 varAngle = 1 / gamma / gamma;
1136 if(verboseLevel > 0)
1137 G4cout << "energy, keV" << "\t" << "Zmu for plate" << G4endl;
1138 for(i = 0; i < 100; ++i)
1139 {
1140 omega = (1.0 + i) * keV;
1141 if(verboseLevel > 1)
1142 G4cout << omega / keV << "\t"
1143 << GetPlateZmuProduct(omega, gamma, varAngle) << "\t";
1144 if(verboseLevel > 0)
1145 outPlate << omega / keV << "\t\t"
1146 << GetPlateZmuProduct(omega, gamma, varAngle) << G4endl;
1147 }
1148 return;
1149}
1150
1152// Calculates the product of linear cof by formation zone for gas.
1153// Omega is energy !!!
1155 G4double varAngle)
1156{
1157 return GetGasFormationZone(omega, gamma, varAngle) *
1158 GetGasLinearPhotoAbs(omega);
1159}
1160
1162// Calculates the product of linear cof by formation zone for gas.
1163// G4cout and output in file in some energy range.
1165{
1166 std::ofstream outGas("gasZmu.dat", std::ios::out);
1167 outGas.setf(std::ios::scientific, std::ios::floatfield);
1168 G4int i;
1169 G4double omega, varAngle, gamma;
1170 gamma = 10000.;
1171 varAngle = 1 / gamma / gamma;
1172 if(verboseLevel > 0)
1173 G4cout << "energy, keV" << "\t" << "Zmu for gas" << G4endl;
1174 for(i = 0; i < 100; ++i)
1175 {
1176 omega = (1.0 + i) * keV;
1177 if(verboseLevel > 1)
1178 G4cout << omega / keV << "\t" << GetGasZmuProduct(omega, gamma, varAngle)
1179 << "\t";
1180 if(verboseLevel > 0)
1181 outGas << omega / keV << "\t\t"
1182 << GetGasZmuProduct(omega, gamma, varAngle) << G4endl;
1183 }
1184 return;
1185}
1186
1188// Computes Compton cross section for plate material in 1/mm
1190{
1191 G4int i, numberOfElements;
1192 G4double xSection = 0., nowZ, sumZ = 0.;
1193
1194 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
1195 numberOfElements = (*theMaterialTable)[fMatIndex1]->GetNumberOfElements();
1196
1197 for(i = 0; i < numberOfElements; ++i)
1198 {
1199 nowZ = (*theMaterialTable)[fMatIndex1]->GetElement(i)->GetZ();
1200 sumZ += nowZ;
1201 xSection += GetComptonPerAtom(omega, nowZ);
1202 }
1203 xSection /= sumZ;
1204 xSection *= (*theMaterialTable)[fMatIndex1]->GetElectronDensity();
1205 return xSection;
1206}
1207
1209// Computes Compton cross section for gas material in 1/mm
1211{
1212 G4int i, numberOfElements;
1213 G4double xSection = 0., nowZ, sumZ = 0.;
1214
1215 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
1216 numberOfElements = (*theMaterialTable)[fMatIndex2]->GetNumberOfElements();
1217
1218 for(i = 0; i < numberOfElements; ++i)
1219 {
1220 nowZ = (*theMaterialTable)[fMatIndex2]->GetElement(i)->GetZ();
1221 sumZ += nowZ;
1222 xSection += GetComptonPerAtom(omega, nowZ);
1223 }
1224 xSection /= sumZ;
1225 xSection *= (*theMaterialTable)[fMatIndex2]->GetElectronDensity();
1226 return xSection;
1227}
1228
1230// Computes Compton cross section per atom with Z electrons for gamma with
1231// the energy GammaEnergy
1233{
1234 G4double CrossSection = 0.0;
1235 if(Z < 0.9999)
1236 return CrossSection;
1237 if(GammaEnergy < 0.1 * keV)
1238 return CrossSection;
1239 if(GammaEnergy > (100. * GeV / Z))
1240 return CrossSection;
1241
1242 static constexpr G4double a = 20.0;
1243 static constexpr G4double b = 230.0;
1244 static constexpr G4double c = 440.0;
1245
1246 static constexpr G4double d1 = 2.7965e-1 * barn, d2 = -1.8300e-1 * barn,
1247 d3 = 6.7527 * barn, d4 = -1.9798e+1 * barn,
1248 e1 = 1.9756e-5 * barn, e2 = -1.0205e-2 * barn,
1249 e3 = -7.3913e-2 * barn, e4 = 2.7079e-2 * barn,
1250 f1 = -3.9178e-7 * barn, f2 = 6.8241e-5 * barn,
1251 f3 = 6.0480e-5 * barn, f4 = 3.0274e-4 * barn;
1252
1253 G4double p1Z = Z * (d1 + e1 * Z + f1 * Z * Z);
1254 G4double p2Z = Z * (d2 + e2 * Z + f2 * Z * Z);
1255 G4double p3Z = Z * (d3 + e3 * Z + f3 * Z * Z);
1256 G4double p4Z = Z * (d4 + e4 * Z + f4 * Z * Z);
1257
1258 G4double T0 = 15.0 * keV;
1259 if(Z < 1.5)
1260 T0 = 40.0 * keV;
1261
1262 G4double X = std::max(GammaEnergy, T0) / electron_mass_c2;
1263 CrossSection =
1264 p1Z * std::log(1. + 2. * X) / X +
1265 (p2Z + p3Z * X + p4Z * X * X) / (1. + a * X + b * X * X + c * X * X * X);
1266
1267 // modification for low energy. (special case for Hydrogen)
1268 if(GammaEnergy < T0)
1269 {
1270 G4double dT0 = 1. * keV;
1271 X = (T0 + dT0) / electron_mass_c2;
1272 G4double sigma =
1273 p1Z * std::log(1. + 2. * X) / X +
1274 (p2Z + p3Z * X + p4Z * X * X) / (1. + a * X + b * X * X + c * X * X * X);
1275 G4double c1 = -T0 * (sigma - CrossSection) / (CrossSection * dT0);
1276 G4double c2 = 0.150;
1277 if(Z > 1.5)
1278 c2 = 0.375 - 0.0556 * std::log(Z);
1279 G4double y = std::log(GammaEnergy / T0);
1280 CrossSection *= std::exp(-y * (c1 + c2 * y));
1281 }
1282 return CrossSection;
1283}
1284
1286// This function returns the spectral and angle density of TR quanta
1287// in X-ray energy region generated forward when a relativistic
1288// charged particle crosses interface between two materials.
1289// The high energy small theta approximation is applied.
1290// (matter1 -> matter2, or 2->1)
1291// varAngle =2* (1 - std::cos(theta)) or approximately = theta*theta
1293 G4double gamma,
1294 G4double varAngle) const
1295{
1296 G4double formationLength1, formationLength2;
1297 formationLength1 =
1298 1.0 / (1.0 / (gamma * gamma) + fSigma1 / (energy * energy) + varAngle);
1299 formationLength2 =
1300 1.0 / (1.0 / (gamma * gamma) + fSigma2 / (energy * energy) + varAngle);
1301 return (varAngle / energy) * (formationLength1 - formationLength2) *
1302 (formationLength1 - formationLength2);
1303}
1304
1306 G4double varAngle)
1307{
1308 // return stack factor corresponding to one interface
1309 return std::real(OneInterfaceXTRdEdx(energy, gamma, varAngle));
1310}
1311
1313// For photon energy distribution tables. Integrate first over angle
1315{
1316 return OneBoundaryXTRNdensity(fEnergy, fGamma, varAngle) *
1317 GetStackFactor(fEnergy, fGamma, varAngle);
1318}
1319
1321// For second integration over energy
1323{
1324 fEnergy = energy;
1326 integral;
1327 return integral.Legendre96(this, &G4VXTRenergyLoss::XTRNSpectralAngleDensity,
1328 0.0, 0.2 * fMaxThetaTR) +
1329 integral.Legendre10(this, &G4VXTRenergyLoss::XTRNSpectralAngleDensity,
1330 0.2 * fMaxThetaTR, fMaxThetaTR);
1331}
1332
1334// for photon angle distribution tables
1336{
1339}
1340
1343{
1344 fVarAngle = varAngle;
1346 integral;
1347 return integral.Legendre96(this, &G4VXTRenergyLoss::XTRNAngleSpectralDensity,
1349}
1350
1352// Check number of photons for a range of Lorentz factors from both energy
1353// and angular tables
1355{
1356 G4int iTkin;
1357 G4double gamma, numberE;
1358
1359 std::ofstream outEn("numberE.dat", std::ios::out);
1360 outEn.setf(std::ios::scientific, std::ios::floatfield);
1361
1362 std::ofstream outAng("numberAng.dat", std::ios::out);
1363 outAng.setf(std::ios::scientific, std::ios::floatfield);
1364
1365 for(iTkin = 0; iTkin < fTotBin; ++iTkin) // Lorentz factor loop
1366 {
1367 gamma =
1369 numberE = (*(*fEnergyDistrTable)(iTkin))(0);
1370 if(verboseLevel > 1)
1371 G4cout << gamma << "\t\t" << numberE << "\t" << G4endl;
1372 if(verboseLevel > 0)
1373 outEn << gamma << "\t\t" << numberE << G4endl;
1374 }
1375 return;
1376}
1377
1379// Returns random energy of a X-ray TR photon for given scaled kinetic energy
1380// of a charged particle
1382{
1383 G4int iTransfer, iPlace;
1384 G4double transfer = 0.0, position, E1, E2, W1, W2, W;
1385
1386 iPlace = iTkin - 1;
1387
1388 if(iTkin == fTotBin) // relativistic plato, try from left
1389 {
1390 position = (*(*fEnergyDistrTable)(iPlace))(0) * G4UniformRand();
1391
1392 for(iTransfer = 0;; ++iTransfer)
1393 {
1394 if(position >= (*(*fEnergyDistrTable)(iPlace))(iTransfer))
1395 break;
1396 }
1397 transfer = GetXTRenergy(iPlace, position, iTransfer);
1398 }
1399 else
1400 {
1401 E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1);
1403 W = 1.0 / (E2 - E1);
1404 W1 = (E2 - scaledTkin) * W;
1405 W2 = (scaledTkin - E1) * W;
1406
1407 position = ((*(*fEnergyDistrTable)(iPlace))(0) * W1 +
1408 (*(*fEnergyDistrTable)(iPlace + 1))(0) * W2) *
1409 G4UniformRand();
1410
1411 for(iTransfer = 0;; ++iTransfer)
1412 {
1413 if(position >= ((*(*fEnergyDistrTable)(iPlace))(iTransfer) *W1 +
1414 (*(*fEnergyDistrTable)(iPlace + 1))(iTransfer) *W2))
1415 break;
1416 }
1417 transfer = GetXTRenergy(iPlace, position, iTransfer);
1418 }
1419 if(transfer < 0.0)
1420 transfer = 0.0;
1421 return transfer;
1422}
1423
1425// Returns approximate position of X-ray photon energy during random sampling
1426// over integral energy distribution
1428{
1429 G4double x1, x2, y1, y2, result;
1430
1431 if(iTransfer == 0)
1432 {
1433 result = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1434 }
1435 else
1436 {
1437 y1 = (*(*fEnergyDistrTable)(iPlace))(iTransfer - 1);
1438 y2 = (*(*fEnergyDistrTable)(iPlace))(iTransfer);
1439
1440 x1 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer - 1);
1441 x2 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1442
1443 if(x1 == x2)
1444 result = x2;
1445 else
1446 {
1447 if(y1 == y2)
1448 result = x1 + (x2 - x1) * G4UniformRand();
1449 else
1450 {
1451 result = x1 + (x2 - x1) * G4UniformRand();
1452 }
1453 }
1454 }
1455 return result;
1456}
1457
1459// Get XTR photon angle at given energy and Tkin
1460
1462{
1463 G4int iTR, iAngle;
1465
1466 if(iTkin == fTotBin)
1467 --iTkin;
1468
1470
1471 for(iTR = 0; iTR < fBinTR; ++iTR)
1472 {
1473 if(energyXTR < fXTREnergyVector->GetLowEdgeEnergy(iTR))
1474 break;
1475 }
1476 if(iTR == fBinTR)
1477 --iTR;
1478
1479 position = (*(*fAngleForEnergyTable)(iTR))(0) * G4UniformRand();
1480 // position = (*(*fAngleForEnergyTable)(iTR))(1) * G4UniformRand(); // ATLAS TB
1481
1482 for(iAngle = 0;; ++iAngle)
1483 // for(iAngle = 1;; ++iAngle) // ATLAS TB
1484 {
1485 if(position >= (*(*fAngleForEnergyTable)(iTR))(iAngle))
1486 break;
1487 }
1488 angle = GetAngleXTR(iTR, position, iAngle);
1489 return angle;
1490}
1491
1493// Returns approximate position of X-ray photon angle at given energy during
1494// random sampling over integral energy distribution
1495
1497 G4int iTransfer)
1498{
1499 G4double x1, x2, y1, y2, result;
1500
1501 if( iTransfer == 0 )
1502 // if( iTransfer == 1 ) // ATLAS TB
1503 {
1504 result = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1505 }
1506 else
1507 {
1508 y1 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer - 1);
1509 y2 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer);
1510
1511 x1 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer - 1);
1512 x2 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1513
1514 if(x1 == x2) result = x2;
1515 else
1516 {
1517 if( y1 == y2 ) result = x1 + (x2 - x1) * G4UniformRand();
1518 else
1519 {
1520 result = x1 + (position - y1) * (x2 - x1) / (y2 - y1);
1521 // result = x1 + 0.1*(position - y1) * (x2 - x1) / (y2 - y1); // ATLAS TB
1522 // result = x1 + 0.05*(position - y1) * (x2 - x1) / (y2 - y1); // ATLAS TB
1523 }
1524 }
1525 }
1526 return result;
1527}
static const G4double e4[47]
static const G4double e1[44]
static const G4double e2[44]
static const G4double e3[45]
static const G4double d1
static const G4double d2
@ fTransitionRadiation
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4ForceCondition
@ NotForced
std::vector< G4Material * > G4MaterialTable
static const G4double T0[78]
G4ProcessType
static constexpr double twopi
Definition: G4SIunits.hh:56
static constexpr double barn
Definition: G4SIunits.hh:85
static constexpr double mm
Definition: G4SIunits.hh:95
static constexpr double keV
Definition: G4SIunits.hh:202
static constexpr double eV
Definition: G4SIunits.hh:201
static constexpr double GeV
Definition: G4SIunits.hh:203
static constexpr double pi
Definition: G4SIunits.hh:55
static constexpr double cm
Definition: G4SIunits.hh:99
static const G4double angle[DIMMOTT]
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
std::complex< G4double > G4complex
Definition: G4Types.hh:88
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
G4VSolid * GetSolid() const
G4Material * GetMaterial() const
G4SandiaTable * GetSandiaTable() const
Definition: G4Material.hh:225
G4double GetElectronDensity() const
Definition: G4Material.hh:213
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:672
const G4String & GetName() const
Definition: G4Material.hh:173
size_t GetIndex() const
Definition: G4Material.hh:256
void AddSecondary(G4Track *aSecondary)
void ProposeEnergy(G4double finalEnergy)
virtual void Initialize(const G4Track &)
G4double GetPDGCharge() const
void PutValue(const std::size_t index, const G4double e, const G4double value)
static G4int GetModelID(const G4int modelIndex)
void clearAndDestroy()
void insertAt(std::size_t, G4PhysicsVector *)
G4double GetLowEdgeEnergy(const std::size_t index) const
void PutValue(const std::size_t index, const G4double value)
G4double GetSandiaCofForMaterial(G4int, G4int) const
const G4VTouchable * GetTouchable() const
G4double GetGlobalTime() const
const G4ThreeVector & GetPosition() const
const G4TouchableHandle & GetTouchableHandle() const
Definition: G4Step.hh:62
G4StepPoint * GetPostStepPoint() const
void Stop()
G4double GetUserElapsed() const
Definition: G4Timer.cc:143
void Start()
G4int GetTrackID() const
G4VPhysicalVolume * GetVolume() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
const G4DynamicParticle * GetDynamicParticle() const
void SetParentID(const G4int aValue)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void SetNumberOfSecondaries(G4int totSecondaries)
G4LogicalVolume * GetLogicalVolume() const
G4int verboseLevel
Definition: G4VProcess.hh:356
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:406
G4VParticleChange * pParticleChange
Definition: G4VProcess.hh:321
const G4String & GetProcessName() const
Definition: G4VProcess.hh:382
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual const G4ThreeVector & GetTranslation(G4int depth=0) const =0
virtual const G4RotationMatrix * GetRotation(G4int depth=0) const =0
G4double GetPlateLinearPhotoAbs(G4double)
G4double AngleSpectralXTRdEdx(G4double energy)
G4double XTRNAngleDensity(G4double varAngle)
G4PhysicsTable * fEnergyDistrTable
G4double GetAngleXTR(G4int iTR, G4double position, G4int iAngle)
virtual G4bool IsApplicable(const G4ParticleDefinition &) override
G4PhysicsTable * fAngleForEnergyTable
static constexpr G4double fMaxProtonTkin
G4PhysicsLogVector * fProtonEnergyVector
G4PhysicsLogVector * fXTREnergyVector
G4double GetGasFormationZone(G4double, G4double, G4double)
G4SandiaTable * fPlatePhotoAbsCof
G4double OneBoundaryXTRNdensity(G4double energy, G4double gamma, G4double varAngle) const
G4PhysicsFreeVector * GetAngleVector(G4double energy, G4int n)
G4PhysicsTable * fAngleDistrTable
G4double GetRandomAngle(G4double energyXTR, G4int iTkin)
G4complex GetPlateComplexFZ(G4double, G4double, G4double)
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
G4complex OneInterfaceXTRdEdx(G4double energy, G4double gamma, G4double varAngle)
virtual G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition) override
G4double GetXTRenergy(G4int iPlace, G4double position, G4int iTransfer)
G4VXTRenergyLoss(G4LogicalVolume *anEnvelope, G4Material *, G4Material *, G4double, G4double, G4int, const G4String &processName="XTRenergyLoss", G4ProcessType type=fElectromagnetic)
G4double XTRNAngleSpectralDensity(G4double energy)
G4double SpectralAngleXTRdEdx(G4double varAngle)
G4double GetXTRrandomEnergy(G4double scaledTkin, G4int iTkin)
G4SandiaTable * fGasPhotoAbsCof
static constexpr G4double fCofTR
G4LogicalVolume * fEnvelope
std::vector< G4PhysicsTable * > fAngleBank
static constexpr G4double fPlasmaCof
virtual ~G4VXTRenergyLoss()
virtual G4double SpectralXTRdEdx(G4double energy)
G4double GetComptonPerAtom(G4double, G4double)
static constexpr G4double fMinProtonTkin
G4double GetGasCompton(G4double)
G4double XTRNSpectralAngleDensity(G4double varAngle)
virtual void ProcessDescription(std::ostream &) const override
G4double GetPlateFormationZone(G4double, G4double, G4double)
G4double GetGasLinearPhotoAbs(G4double)
G4double XTRNSpectralDensity(G4double energy)
virtual G4double GetStackFactor(G4double energy, G4double gamma, G4double varAngle)
G4ParticleDefinition * fPtrGamma
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
G4ParticleChange fParticleChange
G4complex GetGasComplexFZ(G4double, G4double, G4double)
G4double GetPlateCompton(G4double)
G4double AngleXTRdEdx(G4double varAngle)
static constexpr double keV
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double energy(const ThreeVector &p, const G4double m)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4bool transform(G4String &input, const G4String &type)
static const G4double Z1[5]
Definition: paraMaker.cc:41
float electron_mass_c2
Definition: hepunit.py:273
float c_light
Definition: hepunit.py:256
float proton_mass_c2
Definition: hepunit.py:274
float hbarc
Definition: hepunit.py:264
#define DBL_MIN
Definition: templates.hh:54
#define DBL_MAX
Definition: templates.hh:62
#define position
Definition: xmlparse.cc:622