Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4BetheHeitler5DModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/standard/src/G4BetheHeitler5DModel.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4BetheHeitler5DModel.cc (Version 10.6.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // -------------------------------------------     27 // -------------------------------------------------------------------
 28 //                                                 28 //
 29 // GEANT4 Class file                               29 // GEANT4 Class file
 30 //                                                 30 //
 31 //                                                 31 //
 32 // File name:     G4BetheHeitler5DModel.cc         32 // File name:     G4BetheHeitler5DModel.cc
 33 //                                                 33 //
 34 // Authors:                                        34 // Authors:
 35 // Igor Semeniouk and Denis Bernard,               35 // Igor Semeniouk and Denis Bernard,
 36 // LLR, Ecole polytechnique & CNRS/IN2P3, 9112     36 // LLR, Ecole polytechnique & CNRS/IN2P3, 91128 Palaiseau, France
 37 //                                                 37 //
 38 // Acknowledgement of the support of the Frenc     38 // Acknowledgement of the support of the French National Research Agency
 39 // (ANR-13-BS05-0002).                             39 // (ANR-13-BS05-0002).
 40 //                                                 40 //
 41 // Reference: Nucl. Instrum. Meth. A 899 (2018     41 // Reference: Nucl. Instrum. Meth. A 899 (2018) 85 (arXiv:1802.08253 [hep-ph])
 42 //            Nucl. Instrum. Meth., A 936 (201     42 //            Nucl. Instrum. Meth., A 936 (2019) 290
 43 //                                                 43 //
 44 // Class Description:                              44 // Class Description:
 45 //                                                 45 //
 46 // Generates the conversion of a high-energy p     46 // Generates the conversion of a high-energy photon to an e+e- pair, either in the field of an
 47 // atomic electron (triplet) or nucleus (nucle     47 // atomic electron (triplet) or nucleus (nuclear).
 48 // Samples the five-dimensional (5D) different     48 // Samples the five-dimensional (5D) differential cross-section analytical expression:
 49 // . Non polarized conversion:                     49 // . Non polarized conversion:
 50 //   H.A. Bethe, W. Heitler, Proc. R. Soc. Lon     50 //   H.A. Bethe, W. Heitler, Proc. R. Soc. Lond. Ser. A 146 (1934) 83.
 51 // . Polarized conversion:                         51 // . Polarized conversion:
 52 //   T. H. Berlin and L. Madansky, Phys. Rev.      52 //   T. H. Berlin and L. Madansky, Phys. Rev. 78 (1950) 623,
 53 //   M. M. May, Phys. Rev. 84 (1951) 265,          53 //   M. M. May, Phys. Rev. 84 (1951) 265,
 54 //   J. M. Jauch and F. Rohrlich, The theory o     54 //   J. M. Jauch and F. Rohrlich, The theory of photons and electrons, 1976.
 55 //                                                 55 //
 56 // All the above expressions are named "Bethe-     56 // All the above expressions are named "Bethe-Heitler" here.
 57 //                                                 57 //
 58 // Bethe & Heitler, put in Feynman diagram par     58 // Bethe & Heitler, put in Feynman diagram parlance, compute only the two dominant diagrams of
 59 // the first order Born development, which is      59 // the first order Born development, which is an excellent approximation for nuclear conversion
 60 // and for high-energy triplet conversion.         60 // and for high-energy triplet conversion.
 61 //                                                 61 //
 62 // Only the linear polarisation of the incomin     62 // Only the linear polarisation of the incoming photon takes part in these expressions.
 63 // The circular polarisation of the incoming p     63 // The circular polarisation of the incoming photon does not (take part) and no polarisation
 64 // is transfered to the final leptons.             64 // is transfered to the final leptons.
 65 //                                                 65 //
 66 // In case conversion takes place in the field     66 // In case conversion takes place in the field of an isolated nucleus or electron, the bare
 67 // Bethe-Heitler expression is used.               67 // Bethe-Heitler expression is used.
 68 //                                                 68 //
 69 // In case the nucleus or the electron are par     69 // In case the nucleus or the electron are part of an atom, the screening of the target field
 70 // by the other electrons of the atom is descr     70 // by the other electrons of the atom is described by a simple form factor, function of q2:
 71 // . nuclear: N.F. Mott, H.S.W. Massey, The Th     71 // . nuclear: N.F. Mott, H.S.W. Massey, The Theory of Atomic Collisions, 1934.
 72 // . triplet: J.A. Wheeler and W.E. Lamb, Phys     72 // . triplet: J.A. Wheeler and W.E. Lamb, Phys. Rev. 55 (1939) 858.
 73 //                                                 73 //
 74 // The nuclear form factor that affects the pr     74 // The nuclear form factor that affects the probability of very large-q2 events, is not considered.
 75 //                                                 75 //
 76 // In principle the code is valid from thresho     76 // In principle the code is valid from threshold, that is from 2 * m_e c^2 for nuclear and from
 77 // 4 * m_e c^2 for triplet, up to infinity, wh     77 // 4 * m_e c^2 for triplet, up to infinity, while in pratice the divergence of the differential
 78 // cross section at small q2 and, at high-ener     78 // cross section at small q2 and, at high-energy, at small polar angle, make it break down at
 79 // some point that depends on machine precisio     79 // some point that depends on machine precision.
 80 //                                                 80 //
 81 // Very-high-energy (above a few tens of TeV)      81 // Very-high-energy (above a few tens of TeV) LPM suppression effects in the normalized differential
 82 // cross-section are not considered.               82 // cross-section are not considered.
 83 //                                                 83 //
 84 // The 5D differential cross section is sample     84 // The 5D differential cross section is sampled without any high-energy nor small
 85 // angle approximation(s).                         85 // angle approximation(s).
 86 // The generation is strictly energy-momentum      86 // The generation is strictly energy-momentum conserving when all particles in the final state
 87 // are taken into account, that is, including      87 // are taken into account, that is, including the recoiling target.
 88 // (In contrast with the BH expressions taken      88 // (In contrast with the BH expressions taken at face values, for which the electron energy is
 89 // taken to be EMinus = GammaEnergy - EPlus)       89 // taken to be EMinus = GammaEnergy - EPlus)
 90 //                                                 90 //
 91 // Tests include the examination of 1D distrib     91 // Tests include the examination of 1D distributions: see TestEm15
 92 //                                                 92 //
 93 // Total cross sections are not computed (we i     93 // Total cross sections are not computed (we inherit from other classes).
 94 // We just convert a photon on a target when a     94 // We just convert a photon on a target when asked to do so.
 95 //                                                 95 //
 96 // Pure nuclear, pure triplet and 1/Z triplet/     96 // Pure nuclear, pure triplet and 1/Z triplet/nuclear mixture can be generated.
 97 //                                                 97 //
 98 // -------------------------------------------     98 // -------------------------------------------------------------------
 99                                                    99 
100 #include "G4BetheHeitler5DModel.hh"               100 #include "G4BetheHeitler5DModel.hh"
101 #include "G4EmParameters.hh"                      101 #include "G4EmParameters.hh"
102                                                   102 
103 #include "G4PhysicalConstants.hh"                 103 #include "G4PhysicalConstants.hh"
104 #include "G4SystemOfUnits.hh"                     104 #include "G4SystemOfUnits.hh"
105 #include "G4Electron.hh"                          105 #include "G4Electron.hh"
106 #include "G4Positron.hh"                          106 #include "G4Positron.hh"
107 #include "G4Gamma.hh"                             107 #include "G4Gamma.hh"
                                                   >> 108 #include "G4MuonPlus.hh"
                                                   >> 109 #include "G4MuonMinus.hh"
108 #include "G4IonTable.hh"                          110 #include "G4IonTable.hh"
109 #include "G4NucleiProperties.hh"                  111 #include "G4NucleiProperties.hh"
110                                                   112 
111 #include "Randomize.hh"                           113 #include "Randomize.hh"
112 #include "G4ParticleChangeForGamma.hh"            114 #include "G4ParticleChangeForGamma.hh"
113 #include "G4Pow.hh"                               115 #include "G4Pow.hh"
114 #include "G4Log.hh"                               116 #include "G4Log.hh"
115 #include "G4Exp.hh"                               117 #include "G4Exp.hh"
116                                                   118 
117 #include "G4LorentzVector.hh"                     119 #include "G4LorentzVector.hh"
118 #include "G4ThreeVector.hh"                       120 #include "G4ThreeVector.hh"
119 #include "G4RotationMatrix.hh"                    121 #include "G4RotationMatrix.hh"
120                                                   122 
121 #include <cassert>                                123 #include <cassert>
122                                                   124 
                                                   >> 125 // // Q : Use enum G4EmProcessSubType hire ?
                                                   >> 126 // enum G45DConversionMode
                                                   >> 127 //   {
                                                   >> 128 //     kEPair, kMuPair
                                                   >> 129 //   };
                                                   >> 130 
123 const G4int kEPair = 0;                           131 const G4int kEPair = 0;
124 const G4int kMuPair = 1;                          132 const G4int kMuPair = 1;
125                                                   133 
126                                                   134 
127 //....oooOO0OOooo........oooOO0OOooo........oo    135 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
128                                                   136 
129 G4BetheHeitler5DModel::G4BetheHeitler5DModel(c    137 G4BetheHeitler5DModel::G4BetheHeitler5DModel(const G4ParticleDefinition* pd,
130                                              c    138                                              const G4String& nam)
131   : G4PairProductionRelModel(pd, nam),         << 139   : G4PairProductionRelModel(pd, nam),fVerbose(1),fConversionType(0),
                                                   >> 140     iraw(false),
132     fLepton1(G4Electron::Definition()),fLepton    141     fLepton1(G4Electron::Definition()),fLepton2(G4Positron::Definition()),
133     fTheMuPlus(nullptr),fTheMuMinus(nullptr),  << 
134     fVerbose(1),                               << 
135     fConversionType(0),                        << 
136     fConvMode(kEPair),                            142     fConvMode(kEPair),
137     iraw(false)                                << 143     fTheMuPlus(G4MuonPlus::Definition()),fTheMuMinus(G4MuonMinus::Definition())
138 {                                                 144 {
139   theIonTable = G4IonTable::GetIonTable();        145   theIonTable = G4IonTable::GetIonTable();
140   //Q: Do we need this on Model                   146   //Q: Do we need this on Model
141   SetLowEnergyLimit(2*fTheElectron->GetPDGMass    147   SetLowEnergyLimit(2*fTheElectron->GetPDGMass());
142 }                                                 148 }
143                                                   149 
144 //....oooOO0OOooo........oooOO0OOooo........oo    150 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
145                                                   151 
146 G4BetheHeitler5DModel::~G4BetheHeitler5DModel( << 152 G4BetheHeitler5DModel::~G4BetheHeitler5DModel()
                                                   >> 153 {}
147                                                   154 
148 //....oooOO0OOooo........oooOO0OOooo........oo    155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
149                                                   156 
150 void G4BetheHeitler5DModel::Initialise(const G    157 void G4BetheHeitler5DModel::Initialise(const G4ParticleDefinition* part,
151                const G4DataVector& vec)           158                const G4DataVector& vec)
152 {                                                 159 {
153   G4PairProductionRelModel::Initialise(part, v    160   G4PairProductionRelModel::Initialise(part, vec);
154                                                   161 
155   G4EmParameters* theManager = G4EmParameters:    162   G4EmParameters* theManager = G4EmParameters::Instance();
156   // place to initialise model parameters         163   // place to initialise model parameters
157   // Verbosity levels: ( Can redefine as neede    164   // Verbosity levels: ( Can redefine as needed, but some consideration )
158   // 0 = nothing                                  165   // 0 = nothing
159   // > 2 print results                            166   // > 2 print results
160   // > 3 print rejection warning from transfor    167   // > 3 print rejection warning from transformation (fix bug from gammaray .. )
161   // > 4 print photon direction & polarisation    168   // > 4 print photon direction & polarisation
162   fVerbose = theManager->Verbose();               169   fVerbose = theManager->Verbose();
163   fConversionType = theManager->GetConversionT << 170   fConversionType  = theManager->GetConversionType();
164   ////////////////////////////////////////////    171   //////////////////////////////////////////////////////////////
165   // iraw :                                       172   // iraw :
166   //      true  : isolated electron or nucleus    173   //      true  : isolated electron or nucleus.
167   //      false : inside atom -> screening for    174   //      false : inside atom -> screening form factor
168   iraw = theManager->OnIsolated();                175   iraw = theManager->OnIsolated();
169   // G4cout << "BH5DModel::Initialise verbose     176   // G4cout << "BH5DModel::Initialise verbose " << fVerbose
170   //   << " isolated " << iraw << " ctype "<<     177   //   << " isolated " << iraw << " ctype "<< fConversionType << G4endl;
171                                                   178 
172   //Q: Do we need this on Model                   179   //Q: Do we need this on Model
173   // The Leptons defined via SetLeptonPair(..)    180   // The Leptons defined via SetLeptonPair(..) method
174   SetLowEnergyLimit(2*CLHEP::electron_mass_c2)    181   SetLowEnergyLimit(2*CLHEP::electron_mass_c2);
                                                   >> 182 
                                                   >> 183   if (fConvMode == kEPair) {
                                                   >> 184     assert(fLepton1->GetPDGEncoding() == fTheElectron->GetPDGEncoding()) ;
                                                   >> 185     if (fVerbose > 3)
                                                   >> 186       G4cout << "BH5DModel::Initialise conversion to e+ e-" << G4endl;
                                                   >> 187   }
                                                   >> 188 
                                                   >> 189   if (fConvMode == kMuPair) {
                                                   >> 190     assert(fLepton1->GetPDGEncoding() == fTheMuMinus->GetPDGEncoding()) ;
                                                   >> 191     if (fVerbose > 3)
                                                   >> 192       G4cout << "BH5DModel::Initialise conversion to mu+ mu-" << G4endl;
                                                   >> 193   }
175 }                                                 194 }
176                                                   195 
177 //....oooOO0OOooo........oooOO0OOooo........oo    196 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
178                                                   197 
179 void G4BetheHeitler5DModel::SetLeptonPair(cons    198 void G4BetheHeitler5DModel::SetLeptonPair(const G4ParticleDefinition* p1,
180          const G4ParticleDefinition* p2)          199          const G4ParticleDefinition* p2)
181 {                                                 200 {
182   G4int pdg1 = p1->GetPDGEncoding();           << 201   // Lepton1 - nagative charged particle
183   G4int pdg2 = p2->GetPDGEncoding();           << 202   if ( p1->GetPDGEncoding() < 0 ){
184   G4int pdg = std::abs(pdg1);                  << 203     if ( p1->GetPDGEncoding() ==
185   if ( pdg1 != -pdg2 || (pdg != 11 && pdg != 1 << 204    G4Positron::Definition()->GetPDGEncoding() ) {
186     G4ExceptionDescription ed;                 << 
187     ed << " Wrong pair of leptons: " << p1->Ge << 
188        << " and " << p1->GetParticleName();    << 
189     G4Exception("G4BetheHeitler5DModel::SetLep << 
190     FatalErrorInArgument, ed, "");             << 
191   } else {                                     << 
192     if ( pdg == 11 ) {                         << 
193       SetConversionMode(kEPair);                  205       SetConversionMode(kEPair);
194       if( pdg1 == 11 ) {                       << 206       fLepton1 = p2;
195   fLepton1 = p1;                               << 207       fLepton2 = p1;
196   fLepton2 = p2;                               << 208       // if (fVerbose)
197       } else {                                 << 
198   fLepton1 = p2;                               << 
199   fLepton2 = p1;                               << 
200       }                                        << 
201       if (fVerbose > 0)                        << 
202   G4cout << "G4BetheHeitler5DModel::SetLeptonP    209   G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
203          << G4endl;                               210          << G4endl;
                                                   >> 211     } else   if ( p1->GetPDGEncoding() ==
                                                   >> 212       G4MuonPlus::Definition()->GetPDGEncoding() ) {
                                                   >> 213       SetConversionMode(kMuPair);
                                                   >> 214       fLepton1 = p2;
                                                   >> 215       fLepton2 = p1;
                                                   >> 216       // if (fVerbose)
                                                   >> 217   G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
                                                   >> 218          << G4endl;
204     } else {                                      219     } else {
                                                   >> 220       // Exception
                                                   >> 221       G4ExceptionDescription ed;
                                                   >> 222       ed << "Model not applicable to particle(s) "
                                                   >> 223    << p1->GetParticleName() << ", "
                                                   >> 224    << p2->GetParticleName();
                                                   >> 225       G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
                                                   >> 226       FatalException, ed);
                                                   >> 227     }
                                                   >> 228   } else {
                                                   >> 229     if ( p1->GetPDGEncoding() ==
                                                   >> 230    G4Electron::Definition()->GetPDGEncoding() ) {
                                                   >> 231       SetConversionMode(kEPair);
                                                   >> 232       fLepton1 = p1;
                                                   >> 233       fLepton2 = p2;
                                                   >> 234       // if (fVerbose)
                                                   >> 235   G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to e+ e-"
                                                   >> 236          << G4endl;
                                                   >> 237     } else   if ( p1->GetPDGEncoding() ==
                                                   >> 238       G4MuonMinus::Definition()->GetPDGEncoding() ) {
205       SetConversionMode(kMuPair);                 239       SetConversionMode(kMuPair);
206       if( pdg1 == 13 ) {                       << 240       fLepton1 = p1;
207   fLepton1 = p1;                               << 241       fLepton2 = p2;
208   fLepton2 = p2;                               << 242       // if (fVerbose)
209       } else {                                 << 
210   fLepton1 = p2;                               << 
211   fLepton2 = p1;                               << 
212       }                                        << 
213       fTheMuPlus = fLepton2;                   << 
214       fTheMuMinus= fLepton1;                   << 
215       if (fVerbose > 0)                        << 
216   G4cout << "G4BetheHeitler5DModel::SetLeptonP    243   G4cout << "G4BetheHeitler5DModel::SetLeptonPair conversion to mu+ mu-"
217          << G4endl;                               244          << G4endl;
                                                   >> 245     } else {
                                                   >> 246       // Exception
                                                   >> 247       G4ExceptionDescription ed;
                                                   >> 248       ed << "Model not applicable to particle(s) "
                                                   >> 249    << p1->GetParticleName() << ", "
                                                   >> 250    << p2->GetParticleName();
                                                   >> 251       G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0002",
                                                   >> 252       FatalException, ed);
218     }                                             253     }
219   }                                               254   }
                                                   >> 255   if ( fLepton1->GetPDGEncoding() != fLepton2->GetAntiPDGEncoding() ) {
                                                   >> 256     G4Exception("G4BetheHeitler5DModel::SetLeptonPair","em0007",
                                                   >> 257     FatalErrorInArgument, "pair must be particle, antiparticle ");
                                                   >> 258       G4cerr << "BH5DModel::SetLeptonPair BAD paricle/anti particle pair"
                                                   >> 259        << fLepton1->GetParticleName() << ", "
                                                   >> 260        << fLepton2->GetParticleName() << G4endl;
                                                   >> 261   }
220 }                                                 262 }
221                                                   263 
222 //....oooOO0OOooo........oooOO0OOooo........oo    264 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
223                                                   265 
224 G4double G4BetheHeitler5DModel::MaxDiffCrossSe    266 G4double G4BetheHeitler5DModel::MaxDiffCrossSection(const G4double* par,
225                                                   267                                                     G4double Z,
226                                                   268                                                     G4double e,
227                                                   269                                                     G4double loge) const
228 {                                                 270 {
229   const G4double Q = e/par[9];                    271   const G4double Q = e/par[9];
230   return par[0] * G4Exp((par[2]+loge*par[4])*l    272   return par[0] * G4Exp((par[2]+loge*par[4])*loge)
231          / (par[1]+ G4Exp(par[3]*loge)+G4Exp(p    273          / (par[1]+ G4Exp(par[3]*loge)+G4Exp(par[5]*loge))
232          * (1+par[7]*G4Exp(par[8]*G4Log(Z))*Q/    274          * (1+par[7]*G4Exp(par[8]*G4Log(Z))*Q/(1+Q));
233 }                                                 275 }
234                                                   276 
235 //....oooOO0OOooo........oooOO0OOooo........oo    277 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
236                                                   278 
237 void                                              279 void
238 G4BetheHeitler5DModel::SampleSecondaries(std::    280 G4BetheHeitler5DModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
239                                          const    281                                          const G4MaterialCutsCouple* couple,
240                                          const    282                                          const G4DynamicParticle* aDynamicGamma,
241                                          G4dou    283                                          G4double, G4double)
242 {                                                 284 {
243   // MeV                                          285   // MeV
244   static const G4double ElectronMass   = CLHEP    286   static const G4double ElectronMass   = CLHEP::electron_mass_c2;
245                                                   287 
246   const G4double LeptonMass = fLepton1->GetPDG    288   const G4double LeptonMass = fLepton1->GetPDGMass();
247   const G4double LeptonMass2  = LeptonMass*Lep    289   const G4double LeptonMass2  = LeptonMass*LeptonMass;
248                                                   290 
249   static const G4double alpha0         = CLHEP    291   static const G4double alpha0         = CLHEP::fine_structure_const;
250     // mm                                         292     // mm
251   static const G4double r0             = CLHEP    293   static const G4double r0             = CLHEP::classic_electr_radius;
252   // mbarn                                        294   // mbarn
253   static const G4double r02            = r0*r0    295   static const G4double r02            = r0*r0*1.e+25;
254   static const G4double twoPi          = CLHEP    296   static const G4double twoPi          = CLHEP::twopi;
255   static const G4double factor         = alpha    297   static const G4double factor         = alpha0 * r02 / (twoPi*twoPi);
256   //  static const G4double factor1        = p    298   //  static const G4double factor1        = pow((6.0 * pi),(1.0/3.0))/(8.*alpha0*ElectronMass);
257   static const G4double factor1        = 2.661    299   static const G4double factor1        = 2.66134007899/(8.*alpha0*ElectronMass);
258   //                                              300   //
259   G4double PairInvMassMin = 2.*LeptonMass;        301   G4double PairInvMassMin = 2.*LeptonMass;
260   G4double TrThreshold =  2.0 * ( (LeptonMass2    302   G4double TrThreshold =  2.0 * ( (LeptonMass2)/ElectronMass + LeptonMass);
261                                                   303 
262   //                                              304   //
263   static const G4double nu[2][10] = {             305   static const G4double nu[2][10] = {
264     //electron                                    306     //electron
265     { 0.0227436, 0.0582046, 3.0322675, 2.82750    307     { 0.0227436, 0.0582046, 3.0322675, 2.8275065, -0.0034004,
266       1.1212766, 1.8989468, 68.3492750, 0.0211    308       1.1212766, 1.8989468, 68.3492750, 0.0211186, 14.4},
267     //muon                                        309     //muon
268     {0.67810E-06, 0.86037E+05, 2.0008395, 1.67    310     {0.67810E-06, 0.86037E+05, 2.0008395, 1.6739719, -0.0057279,
269      1.4222, 0.0, 263230.0, 0.0521, 51.1338}      311      1.4222, 0.0, 263230.0, 0.0521, 51.1338}
270   };                                              312   };
271   static const G4double tr[2][10] = {             313   static const G4double tr[2][10] = {
272     //electron                                    314     //electron
273     { 0.0332350, 4.3942537, 2.8515925,  2.6351    315     { 0.0332350, 4.3942537, 2.8515925,  2.6351695, -0.0031510,
274       1.5737305, 1.8104647, 20.6434021, -0.027    316       1.5737305, 1.8104647, 20.6434021, -0.0272586, 28.9},
275     //muon                                        317     //muon
276     {0.10382E-03, 0.14408E+17, 4.1368679, 3.26    318     {0.10382E-03, 0.14408E+17, 4.1368679, 3.2662121, -0.0163091,
277      0.0000, 0.0, 0.0, 0.0000, 1.0000}            319      0.0000, 0.0, 0.0, 0.0000, 1.0000}
278   };                                              320   };
279   //                                              321   //
280   static const G4double para[2][3][2] = {         322   static const G4double para[2][3][2] = {
281     //electron                                    323     //electron
282     { {11., -16.},{-1.17, -2.95},{-2., -0.5} }    324     { {11., -16.},{-1.17, -2.95},{-2., -0.5} },
283     //muon                                        325     //muon
284     { {17.5, 1.},{-1.17, -2.95},{2., 6.} }        326     { {17.5, 1.},{-1.17, -2.95},{2., 6.} }
285   };                                              327   };
286   //                                              328   //
287   static const G4double correctionIndex = 1.4;    329   static const G4double correctionIndex = 1.4;
288   //                                              330   //
289   const G4double GammaEnergy  = aDynamicGamma-    331   const G4double GammaEnergy  = aDynamicGamma->GetKineticEnergy();
290   // Protection, Will not be true tot cross se    332   // Protection, Will not be true tot cross section = 0
291   if ( GammaEnergy <= PairInvMassMin) { return    333   if ( GammaEnergy <= PairInvMassMin) { return; }
292                                                   334 
293   const G4double GammaEnergy2 = GammaEnergy*Ga    335   const G4double GammaEnergy2 = GammaEnergy*GammaEnergy;
294                                                   336 
295   ////////////////////////////////////////////    337   //////////////////////////////////////////////////////////////
296   const G4ParticleMomentum GammaDirection =       338   const G4ParticleMomentum GammaDirection =
297     aDynamicGamma->GetMomentumDirection();        339     aDynamicGamma->GetMomentumDirection();
298   G4ThreeVector GammaPolarization = aDynamicGa    340   G4ThreeVector GammaPolarization = aDynamicGamma->GetPolarization();
299                                                   341 
300   // The protection polarization perpendicular    342   // The protection polarization perpendicular to the direction vector,
301   // as it done in G4LivermorePolarizedGammaCo    343   // as it done in G4LivermorePolarizedGammaConversionModel,
302   // assuming Direction is unitary vector         344   // assuming Direction is unitary vector
303   //  (projection to plane) p_proj = p - (p o     345   //  (projection to plane) p_proj = p - (p o d)/(d o d) x d
304   if ( GammaPolarization.howOrthogonal(GammaDi    346   if ( GammaPolarization.howOrthogonal(GammaDirection) != 0) {
305     GammaPolarization -= GammaPolarization.dot    347     GammaPolarization -= GammaPolarization.dot(GammaDirection) * GammaDirection;
306   }                                               348   }
307   // End of Protection                            349   // End of Protection
308   //                                              350   //
309   const G4double GammaPolarizationMag = GammaP    351   const G4double GammaPolarizationMag = GammaPolarization.mag();
310                                                << 352 
311   ////////////////////////////////////////////    353   //////////////////////////////////////////////////////////////
312   // target element                               354   // target element
313   // select randomly one element constituting     355   // select randomly one element constituting the material
314   const G4Element* anElement  = SelectTargetAt    356   const G4Element* anElement  = SelectTargetAtom(couple, fTheGamma, GammaEnergy,
315                                          aDyna    357                                          aDynamicGamma->GetLogKineticEnergy() );
316   // Atomic number                                358   // Atomic number
317   const G4int Z       = anElement->GetZasInt()    359   const G4int Z       = anElement->GetZasInt();
318   const G4int A       = SelectIsotopeNumber(an    360   const G4int A       = SelectIsotopeNumber(anElement);
319   const G4double iZ13 = 1./anElement->GetIonis    361   const G4double iZ13 = 1./anElement->GetIonisation()->GetZ3();
320   const G4double targetMass = G4NucleiProperti    362   const G4double targetMass = G4NucleiProperties::GetNuclearMass(A, Z);
321                                                   363 
322   const G4double NuThreshold =   2.0 * ( (Lept    364   const G4double NuThreshold =   2.0 * ( (LeptonMass2)/targetMass + LeptonMass);
323   // No conversion possible below nuclear thre    365   // No conversion possible below nuclear threshold
324   if ( GammaEnergy <= NuThreshold) { return; }    366   if ( GammaEnergy <= NuThreshold) { return; }
325                                                   367 
326   CLHEP::HepRandomEngine* rndmEngine = G4Rando    368   CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
327                                                   369 
328   // itriplet : true -- triplet, false -- nucl    370   // itriplet : true -- triplet, false -- nuclear.
329   G4bool itriplet = false;                        371   G4bool itriplet = false;
330   if (fConversionType == 1) {                     372   if (fConversionType == 1) {
331     itriplet = false;                             373     itriplet = false;
332   } else if (fConversionType == 2) {              374   } else if (fConversionType == 2) {
333     itriplet = true;                              375     itriplet = true;
334     if ( GammaEnergy <= TrThreshold ) return;     376     if ( GammaEnergy <= TrThreshold ) return;
335   } else if ( GammaEnergy > TrThreshold ) {       377   } else if ( GammaEnergy > TrThreshold ) {
336     // choose triplet or nuclear from a triple    378     // choose triplet or nuclear from a triplet/nuclear=1/Z
337     // total cross section ratio.                 379     // total cross section ratio.
338     // approximate at low energies !              380     // approximate at low energies !
339     if(rndmEngine->flat()*(Z+1) < 1.)  {          381     if(rndmEngine->flat()*(Z+1) < 1.)  {
340       itriplet = true;                            382       itriplet = true;
341     }                                             383     }
342   }                                               384   }
343                                                   385 
344   //                                              386   //
345   const G4double RecoilMass  = itriplet ? Elec    387   const G4double RecoilMass  = itriplet ? ElectronMass : targetMass;
346   const G4double RecoilMass2 = RecoilMass*Reco    388   const G4double RecoilMass2 = RecoilMass*RecoilMass;
347   const G4double sCMS        = 2.*RecoilMass*G    389   const G4double sCMS        = 2.*RecoilMass*GammaEnergy + RecoilMass2;
348   const G4double sCMSPlusRM2 = sCMS + RecoilMa    390   const G4double sCMSPlusRM2 = sCMS + RecoilMass2;
349   const G4double sqrts       = std::sqrt(sCMS)    391   const G4double sqrts       = std::sqrt(sCMS);
350   const G4double isqrts2     = 1./(2.*sqrts);     392   const G4double isqrts2     = 1./(2.*sqrts);
351   //                                              393   //
352   const G4double PairInvMassMax   = sqrts-Reco    394   const G4double PairInvMassMax   = sqrts-RecoilMass;
353   const G4double PairInvMassRange = PairInvMas    395   const G4double PairInvMassRange = PairInvMassMax/PairInvMassMin;
354   const G4double lnPairInvMassRange = G4Log(Pa    396   const G4double lnPairInvMassRange = G4Log(PairInvMassRange);
355                                                   397 
356   // initial state. Defines z axis of "0" fram    398   // initial state. Defines z axis of "0" frame as along photon propagation.
357   // Since CMS(0., 0., GammaEnergy, GammaEnerg    399   // Since CMS(0., 0., GammaEnergy, GammaEnergy+RecoilMass) set some constants
358   const G4double betaCMS = G4LorentzVector(0.0    400   const G4double betaCMS = G4LorentzVector(0.0,0.0,GammaEnergy,GammaEnergy+RecoilMass).beta();
359                                                   401 
360   // maximum value of pdf                         402   // maximum value of pdf
361   const G4double EffectiveZ = iraw ? 0.5 : Z;     403   const G4double EffectiveZ = iraw ? 0.5 : Z;
362   const G4double Threshold  = itriplet ? TrThr    404   const G4double Threshold  = itriplet ? TrThreshold : NuThreshold;
363   const G4double AvailableEnergy    = GammaEne    405   const G4double AvailableEnergy    = GammaEnergy - Threshold;
364   const G4double LogAvailableEnergy = G4Log(Av    406   const G4double LogAvailableEnergy = G4Log(AvailableEnergy);
365   //                                              407   //
366   const G4double MaxDiffCross = itriplet          408   const G4double MaxDiffCross = itriplet
367     ? MaxDiffCrossSection(tr[fConvMode],          409     ? MaxDiffCrossSection(tr[fConvMode],
368         EffectiveZ, AvailableEnergy, LogAvaila    410         EffectiveZ, AvailableEnergy, LogAvailableEnergy)
369     : MaxDiffCrossSection(nu[fConvMode],          411     : MaxDiffCrossSection(nu[fConvMode],
370            EffectiveZ, AvailableEnergy, LogAva    412            EffectiveZ, AvailableEnergy, LogAvailableEnergy);
371   //                                              413   //
372   // 50% safety marging factor                    414   // 50% safety marging factor
373   const G4double ymax = 1.5 * MaxDiffCross;       415   const G4double ymax = 1.5 * MaxDiffCross;
374   // x1 bounds                                    416   // x1 bounds
375   const G4double xu1 =   (LogAvailableEnergy >    417   const G4double xu1 =   (LogAvailableEnergy > para[fConvMode][2][0])
376         ? para[fConvMode][0][0] +                 418         ? para[fConvMode][0][0] +
377         para[fConvMode][1][0]*LogAvailableEner    419         para[fConvMode][1][0]*LogAvailableEnergy
378                        : para[fConvMode][0][0]    420                        : para[fConvMode][0][0] +
379         para[fConvMode][2][0]*para[fConvMode][    421         para[fConvMode][2][0]*para[fConvMode][1][0];
380   const G4double xl1 =   (LogAvailableEnergy >    422   const G4double xl1 =   (LogAvailableEnergy > para[fConvMode][2][1])
381                        ? para[fConvMode][0][1]    423                        ? para[fConvMode][0][1] +
382         para[fConvMode][1][1]*LogAvailableEner    424         para[fConvMode][1][1]*LogAvailableEnergy
383                        : para[fConvMode][0][1]    425                        : para[fConvMode][0][1] +
384         para[fConvMode][2][1]*para[fConvMode][    426         para[fConvMode][2][1]*para[fConvMode][1][1];
385   //                                              427   //
386   G4LorentzVector Recoil;                         428   G4LorentzVector Recoil;
387   G4LorentzVector LeptonPlus;                     429   G4LorentzVector LeptonPlus;
388   G4LorentzVector LeptonMinus;                    430   G4LorentzVector LeptonMinus;
389   G4double pdf    = 0.;                           431   G4double pdf    = 0.;
390                                                   432 
391   G4double rndmv6[6] = {0.0};                  << 433   G4double rndmv6[6];
392   const G4double corrFac = 1.0/(correctionInde << 
393   const G4double expLowLim = -20.;             << 
394   const G4double logLowLim = G4Exp(expLowLim/c << 
395   G4double z0, z1, z2, x0, x1;                 << 
396   G4double betheheitler, sinTheta, cosTheta, d << 
397   // START Sampling                               434   // START Sampling
398   do {                                            435   do {
399                                                   436 
400     rndmEngine->flatArray(6, rndmv6);             437     rndmEngine->flatArray(6, rndmv6);
401                                                   438 
402     //////////////////////////////////////////    439     //////////////////////////////////////////////////
403     // pdf  pow(x,c) with c = 1.4                 440     // pdf  pow(x,c) with c = 1.4
404     // integral y = pow(x,(c+1))/(c+1) @ x = 1    441     // integral y = pow(x,(c+1))/(c+1) @ x = 1 =>  y = 1 /(1+c)
405     // invCdf exp( log(y /* *( c + 1.0 )/ (c +    442     // invCdf exp( log(y /* *( c + 1.0 )/ (c + 1.0 ) */ ) /( c + 1.0) )
406     //////////////////////////////////////////    443     //////////////////////////////////////////////////
                                                   >> 444     const G4double X1 =
                                                   >> 445       G4Exp(G4Log(rndmv6[0])/(correctionIndex + 1.0));
407                                                   446 
408     z0 = (rndmv6[0] > logLowLim) ? G4Log(rndmv << 447     const G4double x0       = G4Exp(xl1 + (xu1 - xl1)*rndmv6[1]);
409     G4double X1 = (z0 > expLowLim) ? G4Exp(z0) << 448     const G4double dum0     = 1./(1.+x0);
410     z1 = xl1 + (xu1 - xl1)*rndmv6[1];          << 449     const G4double cosTheta = (x0-1.)*dum0;
411     if (z1 > expLowLim) {                      << 450     const G4double sinTheta = std::sqrt(4.*x0)*dum0;
412       x0 = G4Exp(z1);                          << 451 
413       dum0 = 1.0/(1.0 + x0);                   << 452     const G4double PairInvMass  = PairInvMassMin*G4Exp(X1*X1*lnPairInvMassRange);
414       x1 = dum0*x0;                            << 
415       cosTheta = -1.0 + 2.0*x1;                << 
416       sinTheta = 2*std::sqrt(x1*(1.0 - x1));   << 
417     } else {                                   << 
418       x0 = 0.0;                                << 
419       dum0 = 1.0;                              << 
420       cosTheta = -1.0;                         << 
421       sinTheta = 0.0;                          << 
422     }                                          << 
423                                                   453 
424     z2 = X1*X1*lnPairInvMassRange;             << 454     //    G4double rndmv3[3];
425     const G4double PairInvMass = PairInvMassMi << 455     //    rndmEngine->flatArray(3, rndmv3);
426                                                   456 
427     // cos and sin theta-lepton                   457     // cos and sin theta-lepton
428     const G4double cosThetaLept = std::cos(pi*    458     const G4double cosThetaLept = std::cos(pi*rndmv6[2]);
429     // sin(ThetaLept) is always in [0,+1] if T    459     // sin(ThetaLept) is always in [0,+1] if ThetaLept is in [0,pi]
430     const G4double sinThetaLept = std::sqrt((1    460     const G4double sinThetaLept = std::sqrt((1.-cosThetaLept)*(1.+cosThetaLept));
431     // cos and sin phi-lepton                     461     // cos and sin phi-lepton
432     const G4double cosPhiLept   = std::cos(two    462     const G4double cosPhiLept   = std::cos(twoPi*rndmv6[3]-pi);
433     // sin(PhiLept) is in [-1,0] if PhiLept in    463     // sin(PhiLept) is in [-1,0] if PhiLept in [-pi,0) and
434     //              is in [0,+1] if PhiLept in    464     //              is in [0,+1] if PhiLept in [0,+pi]
435     const G4double sinPhiLept   = std::copysig    465     const G4double sinPhiLept   = std::copysign(std::sqrt((1.-cosPhiLept)*(1.+cosPhiLept)),rndmv6[3]-0.5);
436     // cos and sin phi                            466     // cos and sin phi
437     const G4double cosPhi       = std::cos(two    467     const G4double cosPhi       = std::cos(twoPi*rndmv6[4]-pi);
438     const G4double sinPhi       = std::copysig << 468     const G4double sinPhi        = std::copysign(std::sqrt((1.-cosPhi)*(1.+cosPhi)),rndmv6[4]-0.5);
439                                                   469 
440     //////////////////////////////////////////    470     //////////////////////////////////////////////////
441     // frames:                                    471     // frames:
442     // 3 : the laboratory Lorentz frame, Geant    472     // 3 : the laboratory Lorentz frame, Geant4 axes definition
443     // 0 : the laboratory Lorentz frame, axes     473     // 0 : the laboratory Lorentz frame, axes along photon direction and polarisation
444     // 1 : the center-of-mass Lorentz frame       474     // 1 : the center-of-mass Lorentz frame
445     // 2 : the pair Lorentz frame                 475     // 2 : the pair Lorentz frame
446     //////////////////////////////////////////    476     //////////////////////////////////////////////////
447                                                   477 
448     // in the center-of-mass frame                478     // in the center-of-mass frame
449                                                   479 
450     const G4double RecEnergyCMS  = (sCMSPlusRM    480     const G4double RecEnergyCMS  = (sCMSPlusRM2-PairInvMass*PairInvMass)*isqrts2;
451     const G4double LeptonEnergy2 = PairInvMass    481     const G4double LeptonEnergy2 = PairInvMass*0.5;
452                                                   482 
453     // New way of calucaltion thePRecoil to av    483     // New way of calucaltion thePRecoil to avoid underflow
454     G4double abp = std::max((2.0*GammaEnergy*R    484     G4double abp = std::max((2.0*GammaEnergy*RecoilMass -
455            PairInvMass*PairInvMass + 2.0*PairI    485            PairInvMass*PairInvMass + 2.0*PairInvMass*RecoilMass)*
456                             (2.0*GammaEnergy*R    486                             (2.0*GammaEnergy*RecoilMass -
457            PairInvMass*PairInvMass - 2.0*PairI    487            PairInvMass*PairInvMass - 2.0*PairInvMass*RecoilMass),0.0);
458                                                   488 
459     G4double thePRecoil = std::sqrt(abp) * isq    489     G4double thePRecoil = std::sqrt(abp) * isqrts2;
460                                                   490 
461     // back to the center-of-mass frame           491     // back to the center-of-mass frame
462     Recoil.set( thePRecoil*sinTheta*cosPhi,       492     Recoil.set( thePRecoil*sinTheta*cosPhi,
463            thePRecoil*sinTheta*sinPhi,            493            thePRecoil*sinTheta*sinPhi,
464            thePRecoil*cosTheta,                   494            thePRecoil*cosTheta,
465            RecEnergyCMS);                         495            RecEnergyCMS);
466                                                   496 
467     // in the pair frame                          497     // in the pair frame
468     const G4double thePLepton    = std::sqrt(     498     const G4double thePLepton    = std::sqrt( (LeptonEnergy2-LeptonMass)
469                                              *    499                                              *(LeptonEnergy2+LeptonMass));
470                                                   500 
471     LeptonPlus.set(thePLepton*sinThetaLept*cos    501     LeptonPlus.set(thePLepton*sinThetaLept*cosPhiLept,
472      thePLepton*sinThetaLept*sinPhiLept,          502      thePLepton*sinThetaLept*sinPhiLept,
473      thePLepton*cosThetaLept,                     503      thePLepton*cosThetaLept,
474      LeptonEnergy2);                              504      LeptonEnergy2);
475                                                   505 
476     LeptonMinus.set(-LeptonPlus.x(),              506     LeptonMinus.set(-LeptonPlus.x(),
477      -LeptonPlus.y(),                             507      -LeptonPlus.y(),
478      -LeptonPlus.z(),                             508      -LeptonPlus.z(),
479      LeptonEnergy2);                              509      LeptonEnergy2);
480                                                   510 
481                                                   511 
482     // Normalisation of final state phase spac    512     // Normalisation of final state phase space:
483     // Section 47 of Particle Data Group, Chin    513     // Section 47 of Particle Data Group, Chin. Phys. C, 40, 100001 (2016)
484     //    const G4double Norme = Recoil1.vect(    514     //    const G4double Norme = Recoil1.vect().mag() * LeptonPlus2.vect().mag();
485     const G4double Norme = Recoil.vect().mag()    515     const G4double Norme = Recoil.vect().mag() * LeptonPlus.vect().mag();
486                                                   516 
487     // e+, e- to CMS frame from pair frame        517     // e+, e- to CMS frame from pair frame
488                                                   518 
489     // boost vector from Pair to CMS              519     // boost vector from Pair to CMS
490     const G4ThreeVector pair2cms =                520     const G4ThreeVector pair2cms =
491     G4LorentzVector( -Recoil.x(), -Recoil.y(),    521     G4LorentzVector( -Recoil.x(), -Recoil.y(), -Recoil.z(),
492          sqrts-RecEnergyCMS).boostVector();       522          sqrts-RecEnergyCMS).boostVector();
493                                                   523 
494     LeptonPlus.boost(pair2cms);                   524     LeptonPlus.boost(pair2cms);
495     LeptonMinus.boost(pair2cms);                  525     LeptonMinus.boost(pair2cms);
496                                                   526 
497     // back to the laboratory frame (make use     527     // back to the laboratory frame (make use of the CMS(0,0,Eg,Eg+RM)) form
498                                                   528 
499     Recoil.boostZ(betaCMS);                       529     Recoil.boostZ(betaCMS);
500     LeptonPlus.boostZ(betaCMS);                   530     LeptonPlus.boostZ(betaCMS);
501     LeptonMinus.boostZ(betaCMS);                  531     LeptonMinus.boostZ(betaCMS);
502                                                   532 
503     // Jacobian factors                           533     // Jacobian factors
504     const G4double Jacob0 = x0*dum0*dum0;         534     const G4double Jacob0 = x0*dum0*dum0;
505     const G4double Jacob1 = 2.*X1*lnPairInvMas    535     const G4double Jacob1 = 2.*X1*lnPairInvMassRange*PairInvMass;
506     const G4double Jacob2 = std::abs(sinThetaL    536     const G4double Jacob2 = std::abs(sinThetaLept);
507                                                   537 
508     // there is no probability to have a lepto << 
509     // X and Y components of momentum may be z << 
510     const G4double EPlus = LeptonPlus.t();        538     const G4double EPlus = LeptonPlus.t();
511     const G4double PPlus = LeptonPlus.vect().m    539     const G4double PPlus = LeptonPlus.vect().mag();
512     const G4double pPX = LeptonPlus.x();       << 540     const G4double sinThetaPlus = LeptonPlus.vect().perp()/PPlus;
513     const G4double pPY = LeptonPlus.y();       << 541     const G4double cosThetaPlus = LeptonPlus.vect().cosTheta();
514     const G4double pPZ = LeptonPlus.z();       << 542 
515     G4double sinPhiPlus = 1.0;                 << 543     const G4double pPX  = LeptonPlus.x();
516     G4double cosPhiPlus = 0.0;                 << 544     const G4double pPY  = LeptonPlus.y();
517     G4double sinThetaPlus = 0.0;               << 545     const G4double dum1 = 1./std::sqrt( pPX*pPX + pPY*pPY );
518     G4double cosThetaPlus = pPZ/PPlus;         << 546     const G4double cosPhiPlus = pPX*dum1;
519     if (cosThetaPlus < 1.0 && cosThetaPlus > - << 547     const G4double sinPhiPlus = pPY*dum1;
520       sinThetaPlus = std::sqrt((1.0 - cosTheta << 
521       sinPhiPlus = pPY/(PPlus*sinThetaPlus);   << 
522       cosPhiPlus = pPX/(PPlus*sinThetaPlus);   << 
523     }                                          << 
524                                                   548 
525     // denominators:                              549     // denominators:
526     // the two cancelling leading terms for fo    550     // the two cancelling leading terms for forward emission at high energy, removed
527     const G4double elMassCTP = LeptonMass*cosT    551     const G4double elMassCTP = LeptonMass*cosThetaPlus;
528     const G4double ePlusSTP  = EPlus*sinThetaP    552     const G4double ePlusSTP  = EPlus*sinThetaPlus;
529     const G4double DPlus     = (elMassCTP*elMa    553     const G4double DPlus     = (elMassCTP*elMassCTP + ePlusSTP*ePlusSTP)
530                               /(EPlus + PPlus*    554                               /(EPlus + PPlus*cosThetaPlus);
531                                                   555 
532     // there is no probability to have a lepto << 
533     // X and Y components of momentum may be z << 
534     const G4double EMinus = LeptonMinus.t();      556     const G4double EMinus = LeptonMinus.t();
535     const G4double PMinus = LeptonMinus.vect()    557     const G4double PMinus = LeptonMinus.vect().mag();
536     const G4double ePX = LeptonMinus.x();      << 558     const G4double sinThetaMinus = LeptonMinus.vect().perp()/PMinus;
537     const G4double ePY = LeptonMinus.y();      << 559     const G4double cosThetaMinus = LeptonMinus.vect().cosTheta();
538     const G4double ePZ = LeptonMinus.z();      << 560 
539     G4double sinPhiMinus = 0.0;                << 561     const G4double ePX  = LeptonMinus.x();
540     G4double cosPhiMinus = 1.0;                << 562     const G4double ePY  = LeptonMinus.y();
541     G4double sinThetaMinus = 0.0;              << 563     const G4double dum2 = 1./std::sqrt( ePX*ePX + ePY*ePY );
542     G4double cosThetaMinus = ePZ/PMinus;       << 564     const G4double cosPhiMinus =  ePX*dum2;
543     if (cosThetaMinus < 1.0 && cosThetaMinus > << 565     const G4double sinPhiMinus =  ePY*dum2;
544       sinThetaMinus = std::sqrt((1.0 - cosThet << 
545       sinPhiMinus = ePY/(PMinus*sinThetaMinus) << 
546       cosPhiMinus = ePX/(PMinus*sinThetaMinus) << 
547     }                                          << 
548                                                   566 
549     const G4double elMassCTM = LeptonMass*cosT    567     const G4double elMassCTM = LeptonMass*cosThetaMinus;
550     const G4double eMinSTM   = EMinus*sinTheta    568     const G4double eMinSTM   = EMinus*sinThetaMinus;
551     const G4double DMinus    = (elMassCTM*elMa    569     const G4double DMinus    = (elMassCTM*elMassCTM + eMinSTM*eMinSTM)
552                               /(EMinus + PMinu    570                               /(EMinus + PMinus*cosThetaMinus);
553                                                   571 
554     // cos(phiMinus-PhiPlus)                      572     // cos(phiMinus-PhiPlus)
555     const G4double cosdPhi = cosPhiPlus*cosPhi    573     const G4double cosdPhi = cosPhiPlus*cosPhiMinus + sinPhiPlus*sinPhiMinus;
556     const G4double PRec    = Recoil.vect().mag    574     const G4double PRec    = Recoil.vect().mag();
557     const G4double q2      = PRec*PRec;           575     const G4double q2      = PRec*PRec;
558                                                   576 
559     const G4double BigPhi  = -LeptonMass2 / (G    577     const G4double BigPhi  = -LeptonMass2 / (GammaEnergy*GammaEnergy2 * q2*q2);
560                                                   578 
561     G4double FormFactor = 1.;                     579     G4double FormFactor = 1.;
562     if (!iraw) {                                  580     if (!iraw) {
563       if (itriplet) {                             581       if (itriplet) {
564   const G4double qun = factor1*iZ13*iZ13;         582   const G4double qun = factor1*iZ13*iZ13;
565   const G4double nun = qun * PRec;                583   const G4double nun = qun * PRec;
566   if (nun < 1.) {                                 584   if (nun < 1.) {
567           FormFactor =  (nun < 0.01) ? (13.8-5    585           FormFactor =  (nun < 0.01) ? (13.8-55.4*std::sqrt(nun))*nun
568                                      : std::sq    586                                      : std::sqrt(1-(nun-1)*(nun-1));
569   } // else FormFactor = 1 by default             587   } // else FormFactor = 1 by default
570       } else {                                    588       } else {
571         const G4double dum3 = 217.*PRec*iZ13;     589         const G4double dum3 = 217.*PRec*iZ13;
572   const G4double AFF  = 1./(1. + dum3*dum3);      590   const G4double AFF  = 1./(1. + dum3*dum3);
573   FormFactor = (1.-AFF)*(1-AFF);                  591   FormFactor = (1.-AFF)*(1-AFF);
574       }                                           592       }
575     } // else FormFactor = 1 by default           593     } // else FormFactor = 1 by default
576                                                   594 
                                                   >> 595     G4double betheheitler;
577     if (GammaPolarizationMag==0.) {               596     if (GammaPolarizationMag==0.) {
578       const G4double pPlusSTP   = PPlus*sinThe    597       const G4double pPlusSTP   = PPlus*sinThetaPlus;
579       const G4double pMinusSTM  = PMinus*sinTh    598       const G4double pMinusSTM  = PMinus*sinThetaMinus;
580       const G4double pPlusSTPperDP  = pPlusSTP    599       const G4double pPlusSTPperDP  = pPlusSTP/DPlus;
581       const G4double pMinusSTMperDM = pMinusST    600       const G4double pMinusSTMperDM = pMinusSTM/DMinus;
582       const G4double dunpol = BigPhi*(            601       const G4double dunpol = BigPhi*(
583                   pPlusSTPperDP *pPlusSTPperDP    602                   pPlusSTPperDP *pPlusSTPperDP *(4.*EMinus*EMinus-q2)
584                 + pMinusSTMperDM*pMinusSTMperD    603                 + pMinusSTMperDM*pMinusSTMperDM*(4.*EPlus*EPlus - q2)
585                 + 2.*pPlusSTPperDP*pMinusSTMpe    604                 + 2.*pPlusSTPperDP*pMinusSTMperDM*cosdPhi
586                     *(4.*EPlus*EMinus + q2 - 2    605                     *(4.*EPlus*EMinus + q2 - 2.*GammaEnergy2)
587                 - 2.*GammaEnergy2*(pPlusSTP*pP    606                 - 2.*GammaEnergy2*(pPlusSTP*pPlusSTP+pMinusSTM*pMinusSTM)/(DMinus*DPlus));
588       betheheitler = dunpol * factor;             607       betheheitler = dunpol * factor;
589     } else {                                      608     } else {
590       const G4double pPlusSTP  = PPlus*sinThet    609       const G4double pPlusSTP  = PPlus*sinThetaPlus;
591       const G4double pMinusSTM = PMinus*sinThe    610       const G4double pMinusSTM = PMinus*sinThetaMinus;
592       const G4double pPlusSTPCPPperDP  = pPlus    611       const G4double pPlusSTPCPPperDP  = pPlusSTP*cosPhiPlus/DPlus;
593       const G4double pMinusSTMCPMperDM = pMinu    612       const G4double pMinusSTMCPMperDM = pMinusSTM*cosPhiMinus/DMinus;
594       const G4double caa = 2.*(EPlus*pMinusSTM    613       const G4double caa = 2.*(EPlus*pMinusSTMCPMperDM+EMinus*pPlusSTPCPPperDP);
595       const G4double cbb = pMinusSTMCPMperDM-p    614       const G4double cbb = pMinusSTMCPMperDM-pPlusSTPCPPperDP;
596       const G4double ccc = (pPlusSTP*pPlusSTP     615       const G4double ccc = (pPlusSTP*pPlusSTP + pMinusSTM*pMinusSTM
597                           +2.*pPlusSTP*pMinusS    616                           +2.*pPlusSTP*pMinusSTM*cosdPhi)/ (DMinus*DPlus);
598       const G4double dtot= 2.*BigPhi*( caa*caa    617       const G4double dtot= 2.*BigPhi*( caa*caa - q2*cbb*cbb - GammaEnergy2*ccc);
599       betheheitler = dtot * factor;               618       betheheitler = dtot * factor;
600     }                                             619     }
601     //                                            620     //
602     const G4double cross =  Norme * Jacob0 * J    621     const G4double cross =  Norme * Jacob0 * Jacob1 * Jacob2 * betheheitler
603                           * FormFactor * Recoi    622                           * FormFactor * RecoilMass / sqrts;
604     pdf = cross * (xu1 - xl1) / G4Exp(correcti    623     pdf = cross * (xu1 - xl1) / G4Exp(correctionIndex*G4Log(X1)); // cond1;
605   } while ( pdf < ymax * rndmv6[5] );             624   } while ( pdf < ymax * rndmv6[5] );
606   // END of Sampling                              625   // END of Sampling
607                                                << 626 
608   if ( fVerbose > 2 ) {                           627   if ( fVerbose > 2 ) {
609     G4double recul = std::sqrt(Recoil.x()*Reco    628     G4double recul = std::sqrt(Recoil.x()*Recoil.x()+Recoil.y()*Recoil.y()
610                               +Recoil.z()*Reco    629                               +Recoil.z()*Recoil.z());
611     G4cout << "BetheHeitler5DModel GammaEnergy    630     G4cout << "BetheHeitler5DModel GammaEnergy= " << GammaEnergy
612      << " PDF= " <<  pdf << " ymax= " << ymax     631      << " PDF= " <<  pdf << " ymax= " << ymax
613            << " recul= " << recul << G4endl;      632            << " recul= " << recul << G4endl;
614   }                                               633   }
615                                                   634 
616   // back to Geant4 system                        635   // back to Geant4 system
617                                                   636 
618   if ( fVerbose > 4 ) {                           637   if ( fVerbose > 4 ) {
619     G4cout << "BetheHeitler5DModel GammaDirect    638     G4cout << "BetheHeitler5DModel GammaDirection " << GammaDirection << G4endl;
620     G4cout << "BetheHeitler5DModel GammaPolari    639     G4cout << "BetheHeitler5DModel GammaPolarization " << GammaPolarization << G4endl;
621     G4cout << "BetheHeitler5DModel GammaEnergy    640     G4cout << "BetheHeitler5DModel GammaEnergy " << GammaEnergy << G4endl;
622     G4cout << "BetheHeitler5DModel Conv "         641     G4cout << "BetheHeitler5DModel Conv "
623      << (itriplet ? "triplet" : "nucl") << G4e    642      << (itriplet ? "triplet" : "nucl") << G4endl;
624   }                                               643   }
625                                                   644 
626   if (GammaPolarizationMag == 0.0) {              645   if (GammaPolarizationMag == 0.0) {
627     // set polarization axis orthohonal to dir    646     // set polarization axis orthohonal to direction
628     GammaPolarization = GammaDirection.orthogo    647     GammaPolarization = GammaDirection.orthogonal().unit();
629   } else {                                        648   } else {
630     // GammaPolarization not a unit vector        649     // GammaPolarization not a unit vector
631     GammaPolarization /= GammaPolarizationMag;    650     GammaPolarization /= GammaPolarizationMag;
632   }                                               651   }
633                                                   652 
634   // The unit norm vector that is orthogonal t    653   // The unit norm vector that is orthogonal to the two others
635   G4ThreeVector yGrec = GammaDirection.cross(G    654   G4ThreeVector yGrec = GammaDirection.cross(GammaPolarization);
636                                                   655 
637   // rotation from  gamma ref. sys. to World      656   // rotation from  gamma ref. sys. to World
638   G4RotationMatrix GtoW(GammaPolarization,yGre    657   G4RotationMatrix GtoW(GammaPolarization,yGrec,GammaDirection);
639                                                   658 
640   Recoil.transform(GtoW);                         659   Recoil.transform(GtoW);
641   LeptonPlus.transform(GtoW);                     660   LeptonPlus.transform(GtoW);
642   LeptonMinus.transform(GtoW);                    661   LeptonMinus.transform(GtoW);
643                                                   662 
644   if ( fVerbose > 2 ) {                           663   if ( fVerbose > 2 ) {
645     G4cout << "BetheHeitler5DModel Recoil " <<    664     G4cout << "BetheHeitler5DModel Recoil " << Recoil.x() << " " << Recoil.y() << " " << Recoil.z()
646      << " " << Recoil.t() << " " << G4endl;       665      << " " << Recoil.t() << " " << G4endl;
647     G4cout << "BetheHeitler5DModel LeptonPlus     666     G4cout << "BetheHeitler5DModel LeptonPlus " << LeptonPlus.x() << " " << LeptonPlus.y() << " "
648      << LeptonPlus.z() << " " << LeptonPlus.t(    667      << LeptonPlus.z() << " " << LeptonPlus.t() << " " << G4endl;
649     G4cout << "BetheHeitler5DModel LeptonMinus    668     G4cout << "BetheHeitler5DModel LeptonMinus " << LeptonMinus.x() << " " << LeptonMinus.y() << " "
650      << LeptonMinus.z() << " " << LeptonMinus.    669      << LeptonMinus.z() << " " << LeptonMinus.t() << " " << G4endl;
651   }                                               670   }
652                                                   671 
653   // Create secondaries                           672   // Create secondaries
654   auto aParticle1 = new G4DynamicParticle(fLep << 673   G4DynamicParticle* aParticle1 = new G4DynamicParticle(fLepton1,LeptonMinus);
655   auto aParticle2 = new G4DynamicParticle(fLep << 674   G4DynamicParticle* aParticle2 = new G4DynamicParticle(fLepton2,LeptonPlus);
656                                                   675 
657   // create G4DynamicParticle object for the p    676   // create G4DynamicParticle object for the particle3 ( recoil )
658   G4ParticleDefinition* RecoilPart;               677   G4ParticleDefinition* RecoilPart;
659   if (itriplet) {                                 678   if (itriplet) {
660     // triplet                                    679     // triplet
661     RecoilPart = fTheElectron;                    680     RecoilPart = fTheElectron;
662   } else{                                         681   } else{
663     RecoilPart = theIonTable->GetIon(Z, A, 0);    682     RecoilPart = theIonTable->GetIon(Z, A, 0);
664   }                                               683   }
665   auto aParticle3 = new G4DynamicParticle(Reco << 684   G4DynamicParticle* aParticle3 = new G4DynamicParticle(RecoilPart,Recoil);
666                                                   685 
667   // Fill output vector                           686   // Fill output vector
668   fvect->push_back(aParticle1);                   687   fvect->push_back(aParticle1);
669   fvect->push_back(aParticle2);                   688   fvect->push_back(aParticle2);
670   fvect->push_back(aParticle3);                   689   fvect->push_back(aParticle3);
671                                                   690 
672   // kill incident photon                         691   // kill incident photon
673   fParticleChange->SetProposedKineticEnergy(0.    692   fParticleChange->SetProposedKineticEnergy(0.);
674   fParticleChange->ProposeTrackStatus(fStopAnd    693   fParticleChange->ProposeTrackStatus(fStopAndKill);
675 }                                                 694 }
676                                                   695 
677 //....oooOO0OOooo........oooOO0OOooo........oo    696 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
678                                                   697