Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4GoudsmitSaundersonMscModel.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/G4GoudsmitSaundersonMscModel.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4GoudsmitSaundersonMscModel.cc (Version 10.3.p3)


  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 // $Id: G4GoudsmitSaundersonMscModel.cc 100399 2016-10-20 07:38:12Z gcosmo $
 26 //                                                 27 //
 27 // -------------------------------------------     28 // ----------------------------------------------------------------------------
 28 //                                                 29 //
 29 // GEANT4 Class implementation file                30 // GEANT4 Class implementation file
 30 //                                                 31 //
 31 // File name:     G4GoudsmitSaundersonMscModel     32 // File name:     G4GoudsmitSaundersonMscModel
 32 //                                                 33 //
 33 // Author:        Mihaly Novak / (Omrane Kadri     34 // Author:        Mihaly Novak / (Omrane Kadri)
 34 //                                                 35 //
 35 // Creation date: 20.02.2009                       36 // Creation date: 20.02.2009
 36 //                                                 37 //
 37 // Modifications:                                  38 // Modifications:
 38 // 04.03.2009 V.Ivanchenko cleanup and format      39 // 04.03.2009 V.Ivanchenko cleanup and format according to Geant4 EM style
 39 // 12.05.2010 O.Kadri: adding Qn1 and Qn12 as      40 // 12.05.2010 O.Kadri: adding Qn1 and Qn12 as private doubles
 40 // 18.05.2015 M. Novak provide PRELIMINARY ver     41 // 18.05.2015 M. Novak provide PRELIMINARY verison of the revised class
 41 //            This class has been revised and      42 //            This class has been revised and updated, new methods added.
 42 //            A new version of Kawrakow-Bielaj     43 //            A new version of Kawrakow-Bielajew Goudsmit-Saunderson MSC model
 43 //            based on the screened Rutherford     44 //            based on the screened Rutherford DCS for elastic scattering of
 44 //            electrons/positrons has been int     45 //            electrons/positrons has been introduced[1,2]. The corresponding MSC
 45 //            angular distributions over a 2D      46 //            angular distributions over a 2D parameter grid have been recomputed
 46 //            and the CDFs are now stored in a     47 //            and the CDFs are now stored in a variable transformed (smooth) form[2,3]
 47 //            together with the corresponding      48 //            together with the corresponding rational interpolation parameters.
 48 //            These angular distributions are      49 //            These angular distributions are handled by the new
 49 //            G4GoudsmitSaundersonTable class      50 //            G4GoudsmitSaundersonTable class that is responsible to sample if
 50 //            it was no, single, few or multip     51 //            it was no, single, few or multiple scattering case and delivers the
 51 //            angular deflection (i.e. cos(the     52 //            angular deflection (i.e. cos(theta) and sin(theta)).
 52 //            Two screening options are provid     53 //            Two screening options are provided:
 53 //             - if fIsUsePWATotalXsecData=TRU     54 //             - if fIsUsePWATotalXsecData=TRUE i.e. SetOptionPWAScreening(TRUE)
 54 //               was called before initialisat     55 //               was called before initialisation: screening parameter value A is
 55 //               determined such that the firs     56 //               determined such that the first transport coefficient G1(A)
 56 //               computed according to the scr     57 //               computed according to the screened Rutherford DCS for elastic
 57 //               scattering will reproduce the     58 //               scattering will reproduce the one computed from the PWA elastic
 58 //               and first transport mean free     59 //               and first transport mean free paths[4].
 59 //             - if fIsUsePWATotalXsecData=FAL     60 //             - if fIsUsePWATotalXsecData=FALSE i.e. default value or
 60 //               SetOptionPWAScreening(FALSE)      61 //               SetOptionPWAScreening(FALSE) was called before initialisation:
 61 //               screening parameter value A i     62 //               screening parameter value A is computed according to Moliere's
 62 //               formula (by using material de     63 //               formula (by using material dependent parameters \chi_cc2 and b_c
 63 //               precomputed for each material     64 //               precomputed for each material used at initialization in
 64 //               G4GoudsmitSaundersonTable) [3     65 //               G4GoudsmitSaundersonTable) [3]
 65 //            Elastic and first trasport mean      66 //            Elastic and first trasport mean free paths are used consistently.
 66 //            The new version is self-consiste     67 //            The new version is self-consistent, several times faster, more
 67 //            robust and accurate compared to      68 //            robust and accurate compared to the earlier version.
 68 //            Spin effects as well as a more a     69 //            Spin effects as well as a more accurate energy loss correction and
 69 //            computations of Lewis moments wi     70 //            computations of Lewis moments will be implemented later on.
 70 // 02.09.2015 M. Novak: first version of new s     71 // 02.09.2015 M. Novak: first version of new step limit is provided.
 71 //            fUseSafetyPlus corresponds to Ur     72 //            fUseSafetyPlus corresponds to Urban fUseSafety (default)
 72 //            fUseDistanceToBoundary correspon     73 //            fUseDistanceToBoundary corresponds to Urban fUseDistanceToBoundary
 73 //            fUseSafety  corresponds to EGSnr     74 //            fUseSafety  corresponds to EGSnrc error-free stepping algorithm
 74 //            Range factor can be significantl     75 //            Range factor can be significantly higher at each case than in Urban.
 75 // 23.08.2017 M. Novak: added corrections to a << 
 76 //            It can be activated by setting t << 
 77 //            before initialization using the  << 
 78 //            The fMottCorrection member is re << 
 79 //            correction (rejection) functions << 
 80 //            Goudsmit-Saunderson agnular dist << 
 81 //            effects and screening correction << 
 82 //            GS angular distributions is: DCS << 
 83 //               # DCS_{SR} is the relativisti << 
 84 //                 solution of the Klein-Gordo << 
 85 //                 scattering of spinless e- o << 
 86 //                 note: the default (without  << 
 87 //                 are based on this DCS_{SR}  << 
 88 //               # DCS_{R} is the Rutherford D << 
 89 //                 screening                   << 
 90 //               # DCS_{Mott} is the Mott DCS  << 
 91 //                 Coulomb potential i.e. scat << 
 92 //                 point-like unscreened Coulo << 
 93 //               # moreover, the screening par << 
 94 //                 the DCS_{cor} with this cor << 
 95 //                 transport cross sections ob << 
 96 //                 (i.e. from elsepa [4])      << 
 97 //            Unlike the default GS, the Mott- << 
 98 //            (different for e- and e+ <= the  << 
 99 //            (Z and material) dependent.      << 
100 // 27.10.2017 M. Novak:                        << 
101 //            - Mott-correction flag is set no << 
102 //            - new form of PWA correction to  << 
103 //            - changed step limit flag conven << 
104 //               # fUseSafety corresponds to U << 
105 //               # fUseDistanceToBoundary corr << 
106 //               # fUseSafetyPlus corresponds  << 
107 // 02.02.2018 M. Novak: implemented CrossSecti << 
108 //                                                 76 //
109 // Class description:                              77 // Class description:
110 //   Kawrakow-Bielajew Goudsmit-Saunderson MSC <<  78 //   Kawrakow-Bielajew Goudsmit-Saunderson MSC model based on the screened
111 //   for elastic scattering of e-/e+. Option,  <<  79 //   Rutherford DCS for elastic scattering of electrons/positrons. Step limitation
112 //   also available now (SetOptionMottCorrecti <<  80 //   algorithm as well as true to geomerty and geometry to true step length
113 //   algorithm (UseSafety) is available beyond <<  81 //   computations are adopted from Urban model[5].
114 //   and true to geomerty and geometry to true << 
115 //   from the Urban model[5]. The most accurat << 
116 //   UseSafetyPlus MSC step limit with Mott-co << 
117 //   are expected to be set through the G4EmPa << 
118 //    # G4EmParameters::Instance()->SetMscStep << 
119 //    # G4EmParameters::Instance()->SetUseMott << 
120 //                                             << 
121 //                                                 82 //
122 // References:                                     83 // References:
123 //   [1] A.F.Bielajew, NIMB 111 (1996) 195-208     84 //   [1] A.F.Bielajew, NIMB 111 (1996) 195-208
124 //   [2] I.Kawrakow, A.F.Bielajew, NIMB 134(19     85 //   [2] I.Kawrakow, A.F.Bielajew, NIMB 134(1998) 325-336
125 //   [3] I.Kawrakow, E.Mainegra-Hing, D.W.O.Ro     86 //   [3] I.Kawrakow, E.Mainegra-Hing, D.W.O.Rogers, F.Tessier,B.R.B.Walters, NRCC
126 //       Report PIRS-701 (2013)                    87 //       Report PIRS-701 (2013)
127 //   [4] F.Salvat, A.Jablonski, C.J. Powell, C     88 //   [4] F.Salvat, A.Jablonski, C.J. Powell, CPC 165(2005) 157-190
128 //   [5] L.Urban, Preprint CERN-OPEN-2006-077      89 //   [5] L.Urban, Preprint CERN-OPEN-2006-077 (2006)
129 //                                                 90 //
130 // -------------------------------------------     91 // -----------------------------------------------------------------------------
131                                                    92 
132                                                    93 
133 #include "G4GoudsmitSaundersonMscModel.hh"         94 #include "G4GoudsmitSaundersonMscModel.hh"
134                                                    95 
135 #include "G4GoudsmitSaundersonTable.hh"            96 #include "G4GoudsmitSaundersonTable.hh"
136 #include "G4GSPWACorrections.hh"               <<  97 #include "G4PWATotalXsecTable.hh"
137                                                    98 
138 #include "G4PhysicalConstants.hh"                  99 #include "G4PhysicalConstants.hh"
139 #include "G4SystemOfUnits.hh"                     100 #include "G4SystemOfUnits.hh"
140                                                   101 
141 #include "G4ParticleChangeForMSC.hh"              102 #include "G4ParticleChangeForMSC.hh"
142 #include "G4DynamicParticle.hh"                   103 #include "G4DynamicParticle.hh"
143 #include "G4Electron.hh"                          104 #include "G4Electron.hh"
144 #include "G4Positron.hh"                          105 #include "G4Positron.hh"
145                                                   106 
146 #include "G4LossTableManager.hh"                  107 #include "G4LossTableManager.hh"
147 #include "G4EmParameters.hh"                   << 
148 #include "G4Track.hh"                             108 #include "G4Track.hh"
149 #include "G4PhysicsTable.hh"                      109 #include "G4PhysicsTable.hh"
150 #include "Randomize.hh"                           110 #include "Randomize.hh"
151 #include "G4Log.hh"                               111 #include "G4Log.hh"
152 #include "G4Exp.hh"                               112 #include "G4Exp.hh"
153 #include "G4Pow.hh"                               113 #include "G4Pow.hh"
154 #include <fstream>                                114 #include <fstream>
155                                                   115 
                                                   >> 116 G4GoudsmitSaundersonTable* G4GoudsmitSaundersonMscModel::fgGSTable      = 0;
                                                   >> 117 G4PWATotalXsecTable*       G4GoudsmitSaundersonMscModel::fgPWAXsecTable = 0;
156                                                   118 
157 // set accurate energy loss and dispalcement s    119 // set accurate energy loss and dispalcement sampling to be always on now
158 G4bool G4GoudsmitSaundersonMscModel::gIsUseAcc << 120 G4bool G4GoudsmitSaundersonMscModel::fgIsUseAccurate = true;
159 // set the usual optimization to be always act    121 // set the usual optimization to be always active now
160 G4bool G4GoudsmitSaundersonMscModel::gIsOptimi << 122 G4bool G4GoudsmitSaundersonMscModel::fgIsOptimizationOn = true;
161                                                << 
162                                                   123 
                                                   >> 124 ////////////////////////////////////////////////////////////////////////////////
163 G4GoudsmitSaundersonMscModel::G4GoudsmitSaunde    125 G4GoudsmitSaundersonMscModel::G4GoudsmitSaundersonMscModel(const G4String& nam)
164   : G4VMscModel(nam) {                         << 126   : G4VMscModel(nam),lowKEnergy(0.1*keV),highKEnergy(1.*GeV) {
165   charge                 = 0;                  << 127   charge               = 0;
166   currentMaterialIndex   = -1;                 << 128   currentMaterialIndex = -1;
167   //                                           << 129 
168   fr                     = 0.1;                << 130   lambdalimit   = 1.*mm ;
169   rangeinit              = 1.e+21;             << 131   fr            = 0.02     ;
170   geombig                = 1.e+50*mm;          << 132   rangeinit     = 0.;
171   geomlimit              = geombig;            << 133   geombig       = 1.e50*mm;
172   tgeom                  = geombig;            << 134   geomlimit     = geombig;
173   tlimit                 = 1.e+10*mm;          << 135   tgeom         = geombig;
174   presafety              = 0.*mm;              << 136   tlimit        = 1.e+10*mm;
175   //                                           << 137   presafety     = 0.*mm;
176   particle               = nullptr;            << 138 
177   theManager             = G4LossTableManager: << 139   particle         = 0;
178   firstStep              = true;               << 140   theManager       = G4LossTableManager::Instance();
179   currentKinEnergy       = 0.0;                << 141   firstStep        = true;
180   currentRange           = 0.0;                << 142   currentKinEnergy = 0.0;
181   //                                           << 143   currentRange     = 0.0;
182   tlimitminfix2          = 1.*nm;              << 144 
183   tausmall               = 1.e-16;             << 145   tlimitminfix2 = 1.*nm;
184   mass                   = electron_mass_c2;   << 146   par1=par2=par3= 0.0;
185   taulim                 = 1.e-6;              << 147   tausmall      = 1.e-16;
186   //                                           << 148   mass          = electron_mass_c2;
187   currentCouple          = nullptr;            << 149   taulim        = 1.e-6;
188   fParticleChange        = nullptr;            << 150 
189   //                                           << 151   currentCouple = 0;
190   fZeff                  = 1.;                 << 152   fParticleChange = 0;
191   //                                           << 153 
192   par1                   = 0.;                 << 154   // by default Moliere screeing parameter will be used but it can be set to the
193   par2                   = 0.;                 << 155   // PWA screening before calling the Initialise method
194   par3                   = 0.;                 << 156   fIsUsePWATotalXsecData = false;
195   //                                           << 157 
196   // Moliere screeing parameter will be used a << 158   //*****************
197   // appalied to the integrated quantities (sc << 159   fLambda0 = 0.0; // elastic mean free path
198   // and second moments) derived from the corr << 160   fLambda1 = 0.0; // first transport mean free path
199   // this PWA correction is ignored if Mott-co << 161   fScrA    = 0.0; // screening parameter
200   // Mott-correction contains all these correc << 162   fG1      = 0.0; // first transport coef.
201   fIsUsePWACorrection    = true;               << 163   //******************
202   //                                           << 164   fTheTrueStepLenght    = 0.;
203   fIsUseMottCorrection   = false;              << 165   fTheTransportDistance = 0.;
204   //                                           << 166   fTheZPathLenght       = 0.;
205   fLambda0               = 0.0; // elastic mea << 
206   fLambda1               = 0.0; // first trans << 
207   fScrA                  = 0.0; // screening p << 
208   fG1                    = 0.0; // first trans << 
209   //                                           << 
210   fMCtoScrA              = 1.0;                << 
211   fMCtoQ1                = 1.0;                << 
212   fMCtoG2PerG1           = 1.0;                << 
213   //                                           << 
214   fTheTrueStepLenght     = 0.;                 << 
215   fTheTransportDistance  = 0.;                 << 
216   fTheZPathLenght        = 0.;                 << 
217   //                                           << 
218   fTheDisplacementVector.set(0.,0.,0.);           167   fTheDisplacementVector.set(0.,0.,0.);
219   fTheNewDirection.set(0.,0.,1.);                 168   fTheNewDirection.set(0.,0.,1.);
220   //                                           << 
221   fIsEverythingWasDone   = false;              << 
222   fIsMultipleSacettring  = false;              << 
223   fIsSingleScattering    = false;              << 
224   fIsEndedUpOnBoundary   = false;              << 
225   fIsNoScatteringInMSC   = false;              << 
226   fIsNoDisplace          = false;              << 
227   fIsInsideSkin          = false;              << 
228   fIsWasOnBoundary       = false;              << 
229   fIsFirstRealStep       = false;              << 
230   rndmEngineMod          = G4Random::getTheEng << 
231   //                                           << 
232   fGSTable               = nullptr;            << 
233   fPWACorrection         = nullptr;            << 
234 }                                              << 
235                                                   169 
                                                   >> 170   fIsEverythingWasDone  = false;
                                                   >> 171   fIsMultipleSacettring = false;
                                                   >> 172   fIsSingleScattering   = false;
                                                   >> 173   fIsEndedUpOnBoundary  = false;
                                                   >> 174   fIsNoScatteringInMSC  = false;
                                                   >> 175   fIsNoDisplace         = false;
                                                   >> 176   fIsInsideSkin         = false;
                                                   >> 177   fIsWasOnBoundary      = false;
                                                   >> 178   fIsFirstRealStep      = false;
236                                                   179 
237 G4GoudsmitSaundersonMscModel::~G4GoudsmitSaund << 180   fZeff = 1.;
238   if (IsMaster()) {                            << 181   //+++++++++++++
239     if (fGSTable) {                            << 182 
240       delete fGSTable;                         << 183   rndmEngineMod = G4Random::getTheEngine();
241       fGSTable = nullptr;                      << 184 
                                                   >> 185   //===================  base
                                                   >> 186   facsafety     = 0.6;
                                                   >> 187 }
                                                   >> 188 
                                                   >> 189 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 190 G4GoudsmitSaundersonMscModel::~G4GoudsmitSaundersonMscModel(){
                                                   >> 191   if(IsMaster()){
                                                   >> 192     if(fgGSTable){
                                                   >> 193       delete fgGSTable;
                                                   >> 194       fgGSTable = 0;
242     }                                             195     }
243     if (fPWACorrection) {                      << 196     if(fgPWAXsecTable){
244       delete fPWACorrection;                   << 197       delete fgPWAXsecTable;
245       fPWACorrection = nullptr;                << 198       fgPWAXsecTable = 0;
246     }                                             199     }
247   }                                               200   }
248 }                                                 201 }
249                                                   202 
250                                                   203 
251 void G4GoudsmitSaundersonMscModel::Initialise( << 204 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 205 void G4GoudsmitSaundersonMscModel::Initialise(const G4ParticleDefinition* p,
                                                   >> 206                                               const G4DataVector&){
252   SetParticle(p);                                 207   SetParticle(p);
253   InitialiseParameters(p);                     << 208   fParticleChange = GetParticleChangeForMSC(p);
254   // -create GoudsmitSaundersonTable and init  << 209   //
255   //  Mott-correction was required             << 210   // -create static GoudsmitSaundersonTable and PWATotalXsecTable is necessary
256   if (IsMaster()) {                            << 211   //
257     // get the Mott-correction flag from EmPar << 212   if(IsMaster()) {
258     if (G4EmParameters::Instance()->UseMottCor << 213 
259       fIsUseMottCorrection = true;             << 214    // Could delete as well if they are exist but then the same data are reloaded
260     }                                          << 215    // in case of e+ for example.
261     // Mott-correction includes other way of P << 216 /*    if(fgGSTable) {
262     // when Mott-correction is activated by th << 217       delete fgGSTable;
263     if (fIsUseMottCorrection) {                << 218       fgGSTable = 0;
264       fIsUsePWACorrection = false;             << 
265     }                                          << 
266     // clear GS-table                          << 
267     if (fGSTable) {                            << 
268       delete fGSTable;                         << 
269       fGSTable = nullptr;                      << 
270     }                                          << 
271     // clear PWA corrections table if any      << 
272     if (fPWACorrection) {                      << 
273       delete fPWACorrection;                   << 
274       fPWACorrection = nullptr;                << 
275     }                                             219     }
276     // create GS-table                         << 220     if(fgPWAXsecTable) {
277     G4bool isElectron = true;                  << 221       delete fgPWAXsecTable;
278     if (p->GetPDGCharge()>0.) {                << 222       fgPWAXsecTable = 0;
279       isElectron = false;                      << 
280     }                                             223     }
281     fGSTable = new G4GoudsmitSaundersonTable(i << 224 */
282     // G4GSTable will be initialised:          << 225     if(!fgGSTable)
283     // - Screened-Rutherford DCS based GS angu << 226       fgGSTable      = new G4GoudsmitSaundersonTable();
284     // - Mott-correction will be initialised i << 227 
285     fGSTable->SetOptionMottCorrection(fIsUseMo << 228     // G4GSTable will be initialised (data are loaded) only if they are not there yet.
286     // - set PWA correction (correction to int << 229     fgGSTable->Initialise();
287     fGSTable->SetOptionPWACorrection(fIsUsePWA << 230 
288     // init                                    << 231     if(fIsUsePWATotalXsecData) {
289     fGSTable->Initialise(LowEnergyLimit(),High << 232       if(!fgPWAXsecTable)
290     // create PWA corrections table if it was  << 233          fgPWAXsecTable = new G4PWATotalXsecTable();
291     if (fIsUsePWACorrection) {                 << 234 
292       fPWACorrection = new G4GSPWACorrections( << 235       // Makes sure that all (and only those) atomic PWA data are in memory that
293       fPWACorrection->Initialise();            << 236       // are in the current MaterilaTable.
                                                   >> 237       fgPWAXsecTable->Initialise();
294     }                                             238     }
295   }                                               239   }
296   fParticleChange = GetParticleChangeForMSC(p) << 
297 }                                              << 
298                                                << 
299                                                << 
300 void G4GoudsmitSaundersonMscModel::InitialiseL << 
301    fGSTable               = static_cast<G4Goud << 
302    fIsUseMottCorrection   = static_cast<G4Goud << 
303    fIsUsePWACorrection    = static_cast<G4Goud << 
304    fPWACorrection         = static_cast<G4Goud << 
305 }                                              << 
306                                                << 
307                                                << 
308 // computes macroscopic first transport cross  << 
309 G4double G4GoudsmitSaundersonMscModel::CrossSe << 
310                                          const << 
311                                          G4dou << 
312                                          G4dou << 
313                                          G4dou << 
314   G4double xsecTr1  = 0.; // cross section per << 
315   //                                           << 
316   fLambda0 = 0.0; // elastic mean free path    << 
317   fLambda1 = 0.0; // first transport mean free << 
318   fScrA    = 0.0; // screening parameter       << 
319   fG1      = 0.0; // first transport coef.     << 
320   // use Moliere's screening (with Mott-corret << 
321   G4double efEnergy = std::max(kineticEnergy,  << 
322   // total mometum square                      << 
323   G4double pt2     = efEnergy*(efEnergy+2.0*el << 
324   // beta square                               << 
325   G4double beta2   = pt2/(pt2+electron_mass_c2 << 
326   // current material index                    << 
327   G4int    matindx = (G4int)mat->GetIndex();   << 
328   // Moliere's b_c                             << 
329   G4double bc      = fGSTable->GetMoliereBc(ma << 
330   // get the Mott-correcton factors if Mott-co << 
331   fMCtoScrA       = 1.0;                       << 
332   fMCtoQ1         = 1.0;                       << 
333   fMCtoG2PerG1    = 1.0;                       << 
334   G4double scpCor = 1.0;                       << 
335   if (fIsUseMottCorrection) {                  << 
336     fGSTable->GetMottCorrectionFactors(G4Log(e << 
337     // ! no scattering power correction since  << 
338     // scpCor = fGSTable->ComputeScatteringPow << 
339   } else if (fIsUsePWACorrection) {            << 
340     fPWACorrection->GetPWACorrectionFactors(G4 << 
341     // scpCor = fGSTable->ComputeScatteringPow << 
342   }                                            << 
343   // screening parameter:                      << 
344   // - if Mott-corretioncorrection: the Screen << 
345   //   screening parameter gives back the (els << 
346   // - if PWA correction: he Screened-Rutherfo << 
347   //   gives back the (elsepa) PWA first trans << 
348   fScrA    = fGSTable->GetMoliereXc2(matindx)/ << 
349   // elastic mean free path in Geant4 internal << 
350   // (if Mott-corretion: the corrected screeni << 
351   // corrected with the screening parameter co << 
352   fLambda0 = beta2*(1.+fScrA)*fMCtoScrA/bc/scp << 
353   // first transport coefficient (if Mott-corr << 
354   // consistent with the one used during the p << 
355   fG1      = 2.0*fScrA*((1.0+fScrA)*G4Log(1.0/ << 
356   // first transport mean free path            << 
357   fLambda1 = fLambda0/fG1;                     << 
358   xsecTr1  = 1./fLambda1;                      << 
359   return xsecTr1;                              << 
360 }                                                 240 }
361                                                   241 
362                                                   242 
                                                   >> 243 ///////////////////////////////////////////////////////////////////////////////
363 // gives back the first transport mean free pa    244 // gives back the first transport mean free path in internal G4 units
364 G4double                                          245 G4double
365 G4GoudsmitSaundersonMscModel::GetTransportMean    246 G4GoudsmitSaundersonMscModel::GetTransportMeanFreePath(const G4ParticleDefinition* /*partdef*/,
366                                                   247                                                        G4double kineticEnergy) {
367   // kinetic energy is assumed to be in Geant4    248   // kinetic energy is assumed to be in Geant4 internal energy unit which is MeV
368   G4double efEnergy = kineticEnergy;              249   G4double efEnergy = kineticEnergy;
369   //                                           << 250   if(efEnergy<lowKEnergy) efEnergy=lowKEnergy;
                                                   >> 251   if(efEnergy>highKEnergy)efEnergy=highKEnergy;
                                                   >> 252 
                                                   >> 253   ///////////////////////////////////////////
370   const G4Material*  mat = currentCouple->GetM    254   const G4Material*  mat = currentCouple->GetMaterial();
371   //                                           << 255 
372   fLambda0 = 0.0; // elastic mean free path       256   fLambda0 = 0.0; // elastic mean free path
373   fLambda1 = 0.0; // first transport mean free    257   fLambda1 = 0.0; // first transport mean free path
374   fScrA    = 0.0; // screening parameter          258   fScrA    = 0.0; // screening parameter
375   fG1      = 0.0; // first transport coef.        259   fG1      = 0.0; // first transport coef.
376                                                   260 
377   // use Moliere's screening (with Mott-corret << 261   if(fIsUsePWATotalXsecData) {
378   if  (efEnergy<10.*CLHEP::eV) efEnergy = 10.* << 262     // use PWA total xsec data to determine screening and lambda0 lambda1
379   // total mometum square                      << 263     const G4ElementVector* theElementVector = mat->GetElementVector();
380   G4double pt2     = efEnergy*(efEnergy+2.0*el << 264     const G4double* theAtomNumDensityVector = mat->GetVecNbOfAtomsPerVolume();
381   // beta square                               << 265     G4int nelm = mat->GetNumberOfElements();
382   G4double beta2   = pt2/(pt2+electron_mass_c2 << 266 
383   // current material index                    << 267     int elowindx = fgPWAXsecTable->GetPWATotalXsecForZet( G4lrint((*theElementVector)[0]->GetZ()) )
384   G4int    matindx = (G4int)mat->GetIndex();   << 268                    ->GetPWATotalXsecEnergyBinIndex(efEnergy);
385   // Moliere's b_c                             << 269     for(G4int i=0;i<nelm;i++){
386   G4double bc      = fGSTable->GetMoliereBc(ma << 270       int zet    = G4lrint((*theElementVector)[i]->GetZ());
387   // get the Mott-correcton factors if Mott-co << 271       // total elastic scattering cross section in Geant4 internal length2 units
388   fMCtoScrA       = 1.0;                       << 272       int indx   = (G4int)(1.5 + charge*1.5); // specify that want to get the total elastic scattering xsection
389   fMCtoQ1         = 1.0;                       << 273       double elxsec = (fgPWAXsecTable->GetPWATotalXsecForZet(zet))->GetInterpXsec(efEnergy,elowindx,indx);
390   fMCtoG2PerG1    = 1.0;                       << 274       // first transport cross section in Geant4 internal length2 units
391   G4double scpCor = 1.0;                       << 275       indx   = (G4int)(2.5 + charge*1.5); // specify that want to get the first tarnsport xsection
392   if (fIsUseMottCorrection) {                  << 276       double t1xsec = (fgPWAXsecTable->GetPWATotalXsecForZet(zet))->GetInterpXsec(efEnergy,elowindx,indx);
393     fGSTable->GetMottCorrectionFactors(G4Log(e << 277       fLambda0 += (theAtomNumDensityVector[i]*elxsec);
394     scpCor = fGSTable->ComputeScatteringPowerC << 278       fLambda1 += (theAtomNumDensityVector[i]*t1xsec);
395   } else if (fIsUsePWACorrection) {            << 279     }
396     fPWACorrection->GetPWACorrectionFactors(G4 << 280     if(fLambda0>0.0) { fLambda0 =1./fLambda0; }
397     // scpCor = fGSTable->ComputeScatteringPow << 281     if(fLambda1>0.0) { fLambda1 =1./fLambda1; }
                                                   >> 282 
                                                   >> 283     // determine screening parameter such that it gives back PWA G1
                                                   >> 284     fG1=0.0;
                                                   >> 285     if(fLambda1>0.0) { fG1 = fLambda0/fLambda1; }
                                                   >> 286 
                                                   >> 287     fScrA = fgGSTable->GetScreeningParam(fG1);
                                                   >> 288   } else {
                                                   >> 289     // Get SCREENING FROM MOLIER
                                                   >> 290 
                                                   >> 291     // below 1 keV it can give bananas so prevet (1 keV)
                                                   >> 292     if(efEnergy<0.001) efEnergy = 0.001;
                                                   >> 293 
                                                   >> 294     // total mometum square in Geant4 internal energy2 units which is MeV2
                                                   >> 295     G4double pt2   = efEnergy*(efEnergy+2.0*electron_mass_c2);
                                                   >> 296     G4double beta2 = pt2/(pt2+electron_mass_c2*electron_mass_c2);
                                                   >> 297     G4int    matindx = mat->GetIndex();
                                                   >> 298     G4double bc = fgGSTable->GetMoliereBc(matindx);
                                                   >> 299     fScrA    = fgGSTable->GetMoliereXc2(matindx)/(4.0*pt2*bc);
                                                   >> 300     // total elastic mean free path in Geant4 internal lenght units
                                                   >> 301     fLambda0 = beta2/bc;//*(1.+fScrA);
                                                   >> 302     fG1      = 2.0*fScrA*((1.0+fScrA)*G4Log(1.0/fScrA+1.0)-1.0);
                                                   >> 303     fLambda1 = fLambda0/fG1;
398   }                                               304   }
399   // screening parameter:                      << 
400   // - if Mott-corretioncorrection: the Screen << 
401   //   screening parameter gives back the (els << 
402   // - if PWA correction: he Screened-Rutherfo << 
403   //   gives back the (elsepa) PWA first trans << 
404   fScrA    = fGSTable->GetMoliereXc2(matindx)/ << 
405   // elastic mean free path in Geant4 internal << 
406   // (if Mott-corretion: the corrected screeni << 
407   // corrected with the screening parameter co << 
408   fLambda0 = beta2*(1.+fScrA)*fMCtoScrA/bc/scp << 
409   // first transport coefficient (if Mott-corr << 
410   // consistent with the one used during the p << 
411   fG1      = 2.0*fScrA*((1.0+fScrA)*G4Log(1.0/ << 
412   // first transport mean free path            << 
413   fLambda1 = fLambda0/fG1;                     << 
414                                                   305 
415   return fLambda1;                                306   return fLambda1;
416 }                                                 307 }
417                                                   308 
418                                                << 309 ////////////////////////////////////////////////////////////////////////////////
419 G4double                                          310 G4double
420 G4GoudsmitSaundersonMscModel::GetTransportMean    311 G4GoudsmitSaundersonMscModel::GetTransportMeanFreePathOnly(const G4ParticleDefinition* /*partdef*/,
421                                                   312                                                        G4double kineticEnergy) {
422   // kinetic energy is assumed to be in Geant4    313   // kinetic energy is assumed to be in Geant4 internal energy unit which is MeV
423   G4double efEnergy = kineticEnergy;              314   G4double efEnergy = kineticEnergy;
424   //                                           << 315   if(efEnergy<lowKEnergy) efEnergy=lowKEnergy;
                                                   >> 316   if(efEnergy>highKEnergy)efEnergy=highKEnergy;
                                                   >> 317 
                                                   >> 318   ///////////////////////////////////////////
425   const G4Material*  mat = currentCouple->GetM    319   const G4Material*  mat = currentCouple->GetMaterial();
426   //                                           << 320 
427   G4double lambda0 = 0.0; // elastc mean free     321   G4double lambda0 = 0.0; // elastc mean free path
428   G4double lambda1 = 0.0; // first transport m    322   G4double lambda1 = 0.0; // first transport mean free path
429   G4double scrA    = 0.0; // screening paramet    323   G4double scrA    = 0.0; // screening parametr
430   G4double g1      = 0.0; // first transport m    324   G4double g1      = 0.0; // first transport mean free path
431                                                   325 
432   // use Moliere's screening (with Mott-corret << 326   if(fIsUsePWATotalXsecData) {
433   if  (efEnergy<10.*CLHEP::eV) efEnergy = 10.* << 327     // use PWA total xsec data to determine screening and lambda0 lambda1
434   // total mometum square in Geant4 internal e << 328     const G4ElementVector* theElementVector = mat->GetElementVector();
435   G4double pt2     = efEnergy*(efEnergy+2.0*el << 329     const G4double* theAtomNumDensityVector = mat->GetVecNbOfAtomsPerVolume();
436   G4double beta2   = pt2/(pt2+electron_mass_c2 << 330     G4int nelm = mat->GetNumberOfElements();
437   G4int    matindx = (G4int)mat->GetIndex();   << 331 
438   G4double bc      = fGSTable->GetMoliereBc(ma << 332     int elowindx = fgPWAXsecTable->GetPWATotalXsecForZet( G4lrint((*theElementVector)[0]->GetZ()) )
439   // get the Mott-correcton factors if Mott-co << 333                    ->GetPWATotalXsecEnergyBinIndex(efEnergy);
440   G4double mctoScrA    = 1.0;                  << 334     for(G4int i=0;i<nelm;i++){
441   G4double mctoQ1      = 1.0;                  << 335       int zet    = G4lrint((*theElementVector)[i]->GetZ());
442   G4double mctoG2PerG1 = 1.0;                  << 336       // first transport cross section in Geant4 internal length2 units
443   G4double scpCor      = 1.0;                  << 337       int indx   = (G4int)(2.5 + charge*1.5); // specify that want to get the first tarnsport xsection
444   if (fIsUseMottCorrection) {                  << 338       double t1xsec = (fgPWAXsecTable->GetPWATotalXsecForZet(zet))->GetInterpXsec(efEnergy,elowindx,indx);
445     fGSTable->GetMottCorrectionFactors(G4Log(e << 339       lambda1 += (theAtomNumDensityVector[i]*t1xsec);
446     scpCor = fGSTable->ComputeScatteringPowerC << 340     }
447   } else if (fIsUsePWACorrection) {            << 341     if(lambda1>0.0) { lambda1 =1./lambda1; }
448     fPWACorrection->GetPWACorrectionFactors(G4 << 342 
449     // scpCor = fGSTable->ComputeScatteringPow << 343   } else {
                                                   >> 344     // Get SCREENING FROM MOLIER
                                                   >> 345 
                                                   >> 346     // below 1 keV it can give bananas so prevet (1 keV)
                                                   >> 347     if(efEnergy<0.001) efEnergy = 0.001;
                                                   >> 348 
                                                   >> 349     // total mometum square in Geant4 internal energy2 units which is MeV2
                                                   >> 350     G4double pt2   = efEnergy*(efEnergy+2.0*electron_mass_c2);
                                                   >> 351     G4double beta2 = pt2/(pt2+electron_mass_c2*electron_mass_c2);
                                                   >> 352     G4int    matindx = mat->GetIndex();
                                                   >> 353     G4double bc = fgGSTable->GetMoliereBc(matindx);
                                                   >> 354     scrA    = fgGSTable->GetMoliereXc2(matindx)/(4.0*pt2*bc);
                                                   >> 355     // total elastic mean free path in Geant4 internal lenght units
                                                   >> 356     lambda0 = beta2/bc;//*(1.+scrA);
                                                   >> 357     g1      = 2.0*scrA*((1.0+scrA)*G4Log(1.0/scrA+1.0)-1.0);
                                                   >> 358     lambda1 = lambda0/g1;
450   }                                               359   }
451   scrA    = fGSTable->GetMoliereXc2(matindx)/( << 
452   // total elastic mean free path in Geant4 in << 
453   lambda0 = beta2*(1.+scrA)*mctoScrA/bc/scpCor << 
454   g1      = 2.0*scrA*((1.0+scrA)*G4Log(1.0/scr << 
455   lambda1 = lambda0/g1;                        << 
456                                                   360 
457   return lambda1;                                 361   return lambda1;
458 }                                                 362 }
459                                                   363 
460                                                << 364 ////////////////////////////////////////////////////////////////////////////////
461 void G4GoudsmitSaundersonMscModel::StartTracki << 365 void G4GoudsmitSaundersonMscModel::StartTracking(G4Track* track)
                                                   >> 366 {
462   SetParticle(track->GetDynamicParticle()->Get    367   SetParticle(track->GetDynamicParticle()->GetDefinition());
463   firstStep = true;                               368   firstStep = true;
464   tlimit    = tgeom = rangeinit = geombig;     << 369   tlimit = tgeom = rangeinit = geombig;
465   rangeinit = 1.e+21;                          << 
466 }                                                 370 }
467                                                   371 
468                                                   372 
469 G4double G4GoudsmitSaundersonMscModel::Compute << 373 ////////////////////////////////////////////////////////////////////////////////
470                                                << 374 G4double G4GoudsmitSaundersonMscModel::ComputeTruePathLengthLimit(
                                                   >> 375                                                   const G4Track& track,
                                                   >> 376                                                   G4double& currentMinimalStep){
                                                   >> 377 
471   G4double skindepth = 0.;                        378   G4double skindepth = 0.;
472   //                                           << 379 
473   const G4DynamicParticle* dp = track.GetDynam    380   const G4DynamicParticle* dp = track.GetDynamicParticle();
474   G4StepPoint* sp             = track.GetStep( << 381 
475   G4StepStatus stepStatus     = sp->GetStepSta << 382   G4StepPoint* sp = track.GetStep()->GetPreStepPoint();
476   currentCouple               = track.GetMater << 383   G4StepStatus stepStatus = sp->GetStepStatus();
                                                   >> 384   currentCouple = track.GetMaterialCutsCouple();
477   SetCurrentCouple(currentCouple);                385   SetCurrentCouple(currentCouple);
478   currentMaterialIndex        = (G4int)current << 386   currentMaterialIndex = currentCouple->GetIndex();
479   currentKinEnergy            = dp->GetKinetic << 387   currentKinEnergy = dp->GetKineticEnergy();
480   currentRange                = GetRange(parti << 388   currentRange = GetRange(particle,currentKinEnergy,currentCouple);
481                                          dp->G << 389 
482   // elastic and first transport mfp, screenin << 390 
483   // (Mott-correction will be used if it was r << 391 
                                                   >> 392   // *** Elastic and first transport mfp, fScrA and fG1 are also set in this !!!
484   fLambda1 = GetTransportMeanFreePath(particle    393   fLambda1 = GetTransportMeanFreePath(particle,currentKinEnergy);
                                                   >> 394 
                                                   >> 395   //
485   // Set initial values:                          396   // Set initial values:
486   //  : lengths are initialised to currentMini    397   //  : lengths are initialised to currentMinimalStep  which is the true, minimum
487   //    step length from all other physics        398   //    step length from all other physics
488   fTheTrueStepLenght    = currentMinimalStep;     399   fTheTrueStepLenght    = currentMinimalStep;
489   fTheTransportDistance = currentMinimalStep;     400   fTheTransportDistance = currentMinimalStep;
490   fTheZPathLenght       = currentMinimalStep;     401   fTheZPathLenght       = currentMinimalStep;  // will need to be converted
491   fTheDisplacementVector.set(0.,0.,0.);           402   fTheDisplacementVector.set(0.,0.,0.);
492   fTheNewDirection.set(0.,0.,1.);                 403   fTheNewDirection.set(0.,0.,1.);
493                                                   404 
494   // Can everything be done in the step limit     405   // Can everything be done in the step limit phase ?
495   fIsEverythingWasDone  = false;                  406   fIsEverythingWasDone  = false;
496   // Multiple scattering needs to be sample ?     407   // Multiple scattering needs to be sample ?
497   fIsMultipleSacettring = false;                  408   fIsMultipleSacettring = false;
498   // Single scattering needs to be sample ?       409   // Single scattering needs to be sample ?
499   fIsSingleScattering   = false;                  410   fIsSingleScattering   = false;
500   // Was zero deflection in multiple scatterin    411   // Was zero deflection in multiple scattering sampling ?
501   fIsNoScatteringInMSC  = false;                  412   fIsNoScatteringInMSC  = false;
502   // Do not care about displacement in MSC sam    413   // Do not care about displacement in MSC sampling
503   // ( used only in the case of gIsOptimizatio << 414   // ( used only in the case of fgIsOptimizationOn = true)
504   fIsNoDisplace = false;                          415   fIsNoDisplace = false;
                                                   >> 416 
505   // get pre-step point safety                    417   // get pre-step point safety
506   presafety = sp->GetSafety();                    418   presafety = sp->GetSafety();
507   //                                           << 419 
                                                   >> 420   // Zeff  = TotNbOfElectPerVolume/TotNbOfAtomsPerVolume
508   fZeff = currentCouple->GetMaterial()->GetIon    421   fZeff = currentCouple->GetMaterial()->GetIonisation()->GetZeffective();
                                                   >> 422 
509   // distance will take into account max-fluct    423   // distance will take into account max-fluct.
510   G4double distance = currentRange;               424   G4double distance = currentRange;
511   distance *= (1.20-fZeff*(1.62e-2-9.22e-5*fZe    425   distance *= (1.20-fZeff*(1.62e-2-9.22e-5*fZeff));
                                                   >> 426 
                                                   >> 427 
                                                   >> 428 
512   //                                              429   //
513   // Possible optimization : if the distance i    430   // Possible optimization : if the distance is samller than the safety -> the
514   // particle will never leave this volume ->     431   // particle will never leave this volume -> dispalcement
515   // as the effect of multiple elastic scatter    432   // as the effect of multiple elastic scattering can be skipped
516   // Important : this optimization can cause p    433   // Important : this optimization can cause problems if one does scoring
517   // in a bigger volume since MSC won't be don    434   // in a bigger volume since MSC won't be done deep inside the volume when
518   // distance < safety so don't use optimized-    435   // distance < safety so don't use optimized-mode in such case.
519   if (gIsOptimizationOn && (distance<presafety << 436   if( fgIsOptimizationOn && (distance < presafety) ) {
520      // Indicate that we need to do MSC after     437      // Indicate that we need to do MSC after transportation and no dispalcement.
521      fIsMultipleSacettring = true;                438      fIsMultipleSacettring = true;
522      fIsNoDisplace = true;                        439      fIsNoDisplace = true;
523   } else if (steppingAlgorithm==fUseDistanceTo << 440   } else if( steppingAlgorithm == fUseDistanceToBoundary ){
524     //Compute geomlimit (and presafety) :      << 441        //Compute geomlimit (and presafety) :
525     // - geomlimit will be:                    << 442        // - geomlimit will be:
526     //    == the straight line distance to the << 443        //    == the straight line distance to the boundary if currentRange is
527     //       longer than that                  << 444        //       longer than that
528     //    == a big value [geombig = 1.e50*mm]  << 445        //    == a big value [geombig = 1.e50*mm] if currentRange is shorter than
529     //       the straight line distance to the << 446        //       the straight line distance to the boundary
530     // - presafety will be updated as well     << 447        // - presafety will be updated as well
531     // So the particle can travell 'gemlimit'  << 448        // So the particle can travell 'gemlimit' distance (along a straight
532     // line!) in its current direction:        << 449        // line!) in its current direction:
533     //  (1) before reaching a boundary (geomli << 450        //  (1) before reaching a boundary (geomlimit < geombig) OR
534     //  (2) before reaching its current range  << 451        //  (2) before reaching its current range (geomlimit == geombig)
535     geomlimit = ComputeGeomLimit(track, presaf << 452        geomlimit = ComputeGeomLimit(track, presafety, currentRange);
536     // Record that the particle is on a bounda << 453 
537     if ( (stepStatus==fGeomBoundary) || (stepS << 454        // Record that the particle is on a boundary
538       fIsWasOnBoundary = true;                 << 455        if( (stepStatus==fGeomBoundary) || (stepStatus==fUndefined && presafety==0.0))
539     }                                          << 456           fIsWasOnBoundary = true;
540     // Set skin depth = skin x elastic_mean_fr << 457 
541     skindepth     = skin*fLambda0;             << 458        // Set skin depth = skin x elastic_mean_free_path
542     // Init the flag that indicates that the p << 459        skindepth = skin*fLambda0;
543     // distance from a boundary                << 460        // Init the flag that indicates that the particle are within a skindepth
544     fIsInsideSkin = false;                     << 461        // distance from a boundary
545     // Check if we can try Single Scattering b << 462        fIsInsideSkin = false;
546     // distance from/to a boundary OR the curr << 463        // Check if we can try Single Scattering because we are within skindepth
547     // shorter than skindepth. NOTICE: the lat << 464        // distance from/to a boundary OR the current minimum true-step-length is
548     // because the MSC angular sampling is fin << 465        // shorter than skindepth. NOTICE: the latest has only efficieny reasons
549     // faster to try single scattering in case << 466        // because the MSC angular sampling is fine for any short steps but much
550     if ((stepStatus==fGeomBoundary) || (presaf << 467        // faster to try single scattering in case of short steps.
551       // check if we are within skindepth dist << 468        if( (stepStatus == fGeomBoundary) || (presafety < skindepth) || (fTheTrueStepLenght < skindepth)){
552       if ((stepStatus == fGeomBoundary) || (pr << 469          // check if we are within skindepth distance from a boundary
553         fIsInsideSkin    = true;               << 470          if( (stepStatus == fGeomBoundary) || (presafety < skindepth))
554         fIsWasOnBoundary = true;               << 471            fIsInsideSkin = true;
555       }                                        << 472          //Try single scattering:
556       //Try single scattering:                 << 473          // - sample distance to next single scattering interaction (sslimit)
557       // - sample distance to next single scat << 474          // - compare to current minimum length
558       // - compare to current minimum length   << 475          //      == if sslimit is the shorter:
559       //      == if sslimit is the shorter:    << 476          //          - set the step length to sslimit
560       //          - set the step length to ssl << 477          //          - indicate that single scattering needs to be done
561       //          - indicate that single scatt << 478          //      == else : nothing to do
562       //      == else : nothing to do          << 479          //- in both cases, the step length was very short so geometrical and
563       //- in both cases, the step length was v << 480          //  true path length are the same
564       //  true path length are the same        << 481          G4double sslimit = -1.*fLambda0*G4Log(rndmEngineMod->flat());
565       G4double sslimit = -1.*fLambda0*G4Log(G4 << 482          // compare to current minimum step length
566       // compare to current minimum step lengt << 483          if(sslimit < fTheTrueStepLenght) {
567       if (sslimit<fTheTrueStepLenght) {        << 484            fTheTrueStepLenght  = sslimit;
568         fTheTrueStepLenght  = sslimit;         << 485            fIsSingleScattering = true;
569         fIsSingleScattering = true;            << 486          }
570       }                                        << 487 
571       // short step -> true step length equal  << 488           // short step -> true step length equal to geometrical path length
572       fTheZPathLenght       = fTheTrueStepLeng << 489           fTheZPathLenght     = fTheTrueStepLenght;
573       // Set taht everything is done in step-l << 490           // Set taht everything is done in step-limit phase so no MSC call
574       // We will check if we need to perform t << 491           // We will check if we need to perform the single-scattering angular
575       // sampling i.e. if single elastic scatt << 492           // sampling i.e. if single elastic scattering was the winer!
576       fIsEverythingWasDone  = true;            << 493           fIsEverythingWasDone = true;
577     } else {                                   << 494        } else {
578       // After checking we know that we cannot << 495        // After checking we know that we cannot try single scattering so we will
579       // need to make an MSC step              << 496        // need to make an MSC step
580       // Indicate that we need to make and MSC << 497          // Indicate that we need to make and MSC step. We do not check if we can
581       // do it now i.e. if presafety>final_tru << 498          // do it now i.e. if presafety>final_true_step_length so we let the
582       // fIsEverythingWasDone = false which in << 499          // fIsEverythingWasDone = false which indicates that we will perform
583       // MSC after transportation.             << 500          // MSC after transportation.
584       fIsMultipleSacettring = true;            << 501          fIsMultipleSacettring = true;
585       // Init the first-real-step falg: it wil << 502 
586       // non-single scattering step in this vo << 503          // Init the first-real-step falg: it will indicate if we do the first
587       fIsFirstRealStep      = false;           << 504          // non-single scattering step in this volume with this particle
588       // If previously the partcile was on bou << 505          fIsFirstRealStep = false;
589       // well. When it is not within skin anym << 506          // If previously the partcile was on boundary it was within skin as
590       // so we make the first real MSC step wi << 507          // well. When it is not within skin anymore it has just left the skin
591       if (fIsWasOnBoundary && !fIsInsideSkin)  << 508          // so we make the first real MSC step with the particle.
592         // reset the 'was on boundary' indicat << 509          if(fIsWasOnBoundary && !fIsInsideSkin){
593         fIsWasOnBoundary  = false;             << 510              // reset the 'was on boundary' indicator flag
594         fIsFirstRealStep  = true;              << 511              fIsWasOnBoundary = false;
595       }                                        << 512              fIsFirstRealStep = true;
596       // If this is the first-real msc step (t << 513          }
597       // skin) or this is the first step with  << 514 
598       // primary):                             << 515          // If this is the first-real msc step (the partcile has just left the
599       //   - set the initial range that will b << 516          // skin) or this is the first step with the particle (was born or
600       //     (only in this volume, because aft << 517          // primary):
601       //     first-real MSC step we will reset << 518          //   - set the initial range that will be used later to limit its step
602       //  - don't let the partcile to cross th << 519          //     (only in this volume, because after boundary crossing at the
603       if (firstStep || fIsFirstRealStep || ran << 520          //     first-real MSC step we will reset)
604         rangeinit = currentRange;              << 521          //  - don't let the partcile to cross the volume just in one step
605         // If geomlimit < geombig than the par << 522          if(firstStep || fIsFirstRealStep){
606         // along its initial direction before  << 523            rangeinit = currentRange;
607         // Otherwise we can be sure that the p << 524            // If geomlimit < geombig than the particle might reach the boundary
608         // before reaching the boundary along  << 525            // along its initial direction before losing its energy (in this step)
609         // geometrical limit appalied. [Howeve << 526            // Otherwise we can be sure that the particle will lose it energy
610         // first or the first-real MSC step. A << 527            // before reaching the boundary along a starigth line so there is no
611         // MSC step the direction will change  << 528            // geometrical limit appalied. [However, tgeom is set only in the
612         // But we will try to end up within sk << 529            // first or the first-real MSC step. After the first or first real
613         // the actual value of geomlimit(See l << 530            // MSC step the direction will change tgeom won't guaranty anything!
614         // boundary).]                         << 531            // But we will try to end up within skindepth from the boundary using
615         if (geomlimit<geombig) {               << 532            // the actual value of geomlimit(See later at step reduction close to
616           // transfrom straight line distance  << 533            // boundary).]
617           // length based on the mean values ( << 534            if(geomlimit < geombig){
618           // first-transport mean free path i. << 535                // transfrom straight line distance to the boundary to real step
619           if ((1.-geomlimit/fLambda1)> 0.) {   << 536                // length based on the mean values (using the prestep point
620             geomlimit = -fLambda1*G4Log(1.-geo << 537                // first-transport mean free path i.e. no energy loss correction)
621           }                                    << 538                if((1.-geomlimit/fLambda1) > 0.)
622           // the 2-different case that could l << 539                  geomlimit = -fLambda1*G4Log(1.-geomlimit/fLambda1);
623           if (firstStep) {                     << 540               // the 2-different case that could lead us here
624             tgeom = 2.*geomlimit/facgeom;      << 541               if(firstStep)
625           } else {                             << 542                 tgeom = 2.*geomlimit/facgeom;
626             tgeom = geomlimit/facgeom;         << 543                else
627           }                                    << 544                 tgeom = geomlimit/facgeom;
628         } else {                               << 545            } else {
629           tgeom = geombig;                     << 546              tgeom = geombig;
630         }                                      << 547            }
631       }                                        << 548          }
632       // True step length limit from range fac << 549 
633       // range is used that was set at the fir << 550          // True step length limit from range factor. Noteice, that the initial
634       // in this volume with this particle.    << 551          // range is used that was set at the first step or first-real MSC step
635       tlimit = facrange*rangeinit;             << 552          // in this volume with this particle.
636       // Take the minimum of the true step len << 553          tlimit = facrange*rangeinit;
637       // geometrical constraint or range-facto << 554          // Take the minimum of the true step length limits coming from
638       tlimit = std::min(tlimit,tgeom);         << 555          // geometrical constraint or range-factor limitation
639       // Step reduction close to boundary: we  << 556          tlimit = std::min(tlimit,tgeom);
640       // from the boundary ( Notice: in case o << 557 
641       // because geomlimit is the straigth lin << 558          // Step reduction close to boundary: we try to end up within skindepth
642       // the currect direction (if geomlimit<g << 559          // from the boundary ( Notice: in case of mag. field it might not work
643       // change the initial direction. So te p << 560          // because geomlimit is the straigth line distance to the boundary in
644       // before in a different direction. Howe << 561          // the currect direction (if geomlimit<geombig) and mag. field can
645       // path length to this (straight line) l << 562          // change the initial direction. So te particle might hit some boundary
646       // transport distance (straight line) wi << 563          // before in a different direction. However, here we restrict the true
647       // geomlimit-0.999*skindepth after the c << 564          // path length to this (straight line) lenght so the corresponding
648       if (geomlimit<geombig) {                 << 565          // transport distance (straight line) will be even shorter than
649         tlimit = std::min(tlimit, geomlimit-0. << 566          // geomlimit-0.999*skindepth after the change of true->geom.
650       }                                        << 567          if(geomlimit < geombig)
651       // randomize 1st step or 1st 'normal' st << 568            tlimit = std::min(tlimit, geomlimit-0.999*skindepth);
652       if (firstStep || fIsFirstRealStep) {     << 569 
653         fTheTrueStepLenght = std::min(fTheTrue << 570          // randomize 1st step or 1st 'normal' step in volume
654       } else {                                 << 571          if(firstStep || fIsFirstRealStep) {
655         fTheTrueStepLenght = std::min(fTheTrue << 572             fTheTrueStepLenght = std::min(fTheTrueStepLenght, Randomizetlimit());
656       }                                        << 573          } else {
                                                   >> 574            fTheTrueStepLenght = std::min(fTheTrueStepLenght, tlimit);
                                                   >> 575          }
657     }                                             576     }
658   } else if (steppingAlgorithm==fUseSafetyPlus << 577   } else if (steppingAlgorithm == fUseSafety) { // THE ERROR_FREE stepping alg.
659     presafety =  ComputeSafety(sp->GetPosition    578     presafety =  ComputeSafety(sp->GetPosition(),fTheTrueStepLenght);
660     geomlimit = presafety;                        579     geomlimit = presafety;
                                                   >> 580 
661     // Set skin depth = skin x elastic_mean_fr    581     // Set skin depth = skin x elastic_mean_free_path
662     skindepth = skin*fLambda0;                    582     skindepth = skin*fLambda0;
663     // Check if we can try Single Scattering b    583     // Check if we can try Single Scattering because we are within skindepth
664     // distance from/to a boundary OR the curr    584     // distance from/to a boundary OR the current minimum true-step-length is
665     // shorter than skindepth. NOTICE: the lat    585     // shorter than skindepth. NOTICE: the latest has only efficieny reasons
666     // because the MSC angular sampling is fin    586     // because the MSC angular sampling is fine for any short steps but much
667     // faster to try single scattering in case    587     // faster to try single scattering in case of short steps.
668     if ((stepStatus==fGeomBoundary) || (presaf << 588     if( (stepStatus == fGeomBoundary) || (presafety < skindepth) || (fTheTrueStepLenght < skindepth)){
669       //Try single scattering:                    589       //Try single scattering:
670       // - sample distance to next single scat    590       // - sample distance to next single scattering interaction (sslimit)
671       // - compare to current minimum length      591       // - compare to current minimum length
672       //      == if sslimit is the shorter:       592       //      == if sslimit is the shorter:
673       //          - set the step length to ssl    593       //          - set the step length to sslimit
674       //          - indicate that single scatt    594       //          - indicate that single scattering needs to be done
675       //      == else : nothing to do             595       //      == else : nothing to do
676       //- in both cases, the step length was v    596       //- in both cases, the step length was very short so geometrical and
677       //  true path length are the same           597       //  true path length are the same
678       G4double sslimit = -1.*fLambda0*G4Log(G4 << 598       G4double sslimit = -1.*fLambda0*G4Log(rndmEngineMod->flat());
679       // compare to current minimum step lengt    599       // compare to current minimum step length
680       if (sslimit<fTheTrueStepLenght) {        << 600       if(sslimit < fTheTrueStepLenght) {
681         fTheTrueStepLenght  = sslimit;            601         fTheTrueStepLenght  = sslimit;
682         fIsSingleScattering = true;               602         fIsSingleScattering = true;
683       }                                           603       }
684       // short step -> true step length equal  << 604 
685       fTheZPathLenght       = fTheTrueStepLeng << 605        // short step -> true step length equal to geometrical path length
686       // Set taht everything is done in step-l << 606        fTheZPathLenght     = fTheTrueStepLenght;
687       // We will check if we need to perform t << 607        // Set taht everything is done in step-limit phase so no MSC call
688       // sampling i.e. if single elastic scatt << 608        // We will check if we need to perform the single-scattering angular
689       fIsEverythingWasDone  = true;            << 609        // sampling i.e. if single elastic scattering was the winer!
                                                   >> 610        fIsEverythingWasDone = true;
690     } else {                                      611     } else {
691       // After checking we know that we cannot << 612     // After checking we know that we cannot try single scattering so we will
692       // need to make an MSC step              << 613     // need to make an MSC step
693       // Indicate that we need to make and MSC    614       // Indicate that we need to make and MSC step.
694       fIsMultipleSacettring = true;               615       fIsMultipleSacettring = true;
695       fIsEverythingWasDone  = true;               616       fIsEverythingWasDone  = true;
                                                   >> 617 
696       // limit from range factor                  618       // limit from range factor
697       fTheTrueStepLenght    = std::min(fTheTru << 619       fTheTrueStepLenght = std::min(fTheTrueStepLenght, facrange*currentRange);
                                                   >> 620 
698       // never let the particle go further tha    621       // never let the particle go further than the safety if we are out of the skin
699       // if we are here we are out of the skin    622       // if we are here we are out of the skin, presafety > 0.
700       if (fTheTrueStepLenght>presafety) {      << 623       if(fTheTrueStepLenght > presafety)
701         fTheTrueStepLenght = std::min(fTheTrue    624         fTheTrueStepLenght = std::min(fTheTrueStepLenght, presafety);
702       }                                        << 625 
703       // make sure that we are still within th    626       // make sure that we are still within the aplicability of condensed histry model
704       // i.e. true step length is not longer t    627       // i.e. true step length is not longer than first transport mean free path.
705       // We schould take into account energy l    628       // We schould take into account energy loss along 0.5x lambda_transport1
706       // step length as well. So let it 0.5 x  << 629       // step length as well. So let it 0.4 x lambda_transport1
707       fTheTrueStepLenght = std::min(fTheTrueSt << 630       fTheTrueStepLenght = std::min(fTheTrueStepLenght, fLambda1*0.4);
708     }                                             631     }
709   } else {                                        632   } else {
                                                   >> 633 
710     // This is the default stepping algorithm:    634     // This is the default stepping algorithm: the fastest but the least
711     // accurate that corresponds to fUseSafety    635     // accurate that corresponds to fUseSafety in Urban model. Note, that GS
712     // model can handle any short steps so we     636     // model can handle any short steps so we do not need the minimum limits
713     //                                         << 637 
714     // NO single scattering in case of skin or    638     // NO single scattering in case of skin or short steps (by defult the MSC
715     // model will be single or even no scatter    639     // model will be single or even no scattering in case of short steps
716     // compared to the elastic mean free path.    640     // compared to the elastic mean free path.)
717     //                                         << 641 
718     // indicate that MSC needs to be done (alw    642     // indicate that MSC needs to be done (always and always after transportation)
719     fIsMultipleSacettring = true;                 643     fIsMultipleSacettring = true;
720     if (stepStatus!=fGeomBoundary) {           << 644 
721       presafety = ComputeSafety(sp->GetPositio << 645       if( stepStatus != fGeomBoundary ) {
722     }                                          << 646         presafety = ComputeSafety(sp->GetPosition(),fTheTrueStepLenght);
723     // Far from boundary-> in optimized mode d << 647       }
724     if ((distance<presafety) && (gIsOptimizati << 648 
725       fIsNoDisplace = true;                    << 649       // Far from boundary-> in optimized mode do not sample dispalcement.
726     } else {                                   << 650       if( (distance < presafety) && (fgIsOptimizationOn)) {
727       // Urban like                            << 651         fIsNoDisplace = true;
728       if (firstStep || (stepStatus==fGeomBound << 652       } else {
729         rangeinit = currentRange;              << 653         // Urban like
730         fr        = facrange;                  << 654         if(firstStep || (stepStatus == fGeomBoundary)) {
                                                   >> 655           rangeinit = currentRange;
                                                   >> 656           fr = facrange;
731 // We don't use this: we won't converge to the    657 // We don't use this: we won't converge to the single scattering results with
732 //                    decreasing range-factor. << 658 //                    decreasing range-factor.          
733 //              rangeinit = std::max(rangeinit    659 //              rangeinit = std::max(rangeinit, fLambda1);
734 //              if(fLambda1 > lambdalimit) {      660 //              if(fLambda1 > lambdalimit) {
735 //                fr *= (0.75+0.25*fLambda1/la    661 //                fr *= (0.75+0.25*fLambda1/lambdalimit);
736 //              }                                 662 //              }
737                                                   663 
                                                   >> 664         }
                                                   >> 665 
                                                   >> 666         //step limit
                                                   >> 667         tlimit = std::max(fr*rangeinit, facsafety*presafety);
                                                   >> 668 
                                                   >> 669         // first step randomization
                                                   >> 670         if(firstStep || stepStatus == fGeomBoundary) {
                                                   >> 671           fTheTrueStepLenght = std::min(fTheTrueStepLenght, Randomizetlimit());
                                                   >> 672         } else {
                                                   >> 673           fTheTrueStepLenght = std::min(fTheTrueStepLenght, tlimit);
                                                   >> 674         }
738       }                                           675       }
739       //step limit                             << 
740       tlimit = std::max(fr*rangeinit, facsafet << 
741       // first step randomization              << 
742       if (firstStep || stepStatus==fGeomBounda << 
743         fTheTrueStepLenght = std::min(fTheTrue << 
744       } else {                                 << 
745         fTheTrueStepLenght = std::min(fTheTrue << 
746       }                                        << 
747     }                                          << 
748   }                                               676   }
749   //                                           << 677 
750   // unset first-step                             678   // unset first-step
751   firstStep =false;                               679   firstStep =false;
                                                   >> 680 
752   // performe single scattering, multiple scat    681   // performe single scattering, multiple scattering if this later can be done safely here
753   if (fIsEverythingWasDone) {                  << 682   if(fIsEverythingWasDone){
754     if (fIsSingleScattering) {                 << 683     if(fIsSingleScattering){
755       // sample single scattering                 684       // sample single scattering
756       //G4double ekin   = 0.5*(currentKinEnerg << 685       G4double cost,sint,cosPhi,sinPhi;
757       G4double lekin  = G4Log(currentKinEnergy << 686       SingleScattering(cost, sint);
758       G4double pt2    = currentKinEnergy*(curr << 687       G4double phi = CLHEP::twopi*rndmEngineMod->flat();
759       G4double beta2  = pt2/(pt2+CLHEP::electr << 688       sinPhi = std::sin(phi);
760       G4double cost   = fGSTable->SingleScatte << 689       cosPhi = std::cos(phi);
761       // protection                            << 
762       if (cost<-1.) cost = -1.;                << 
763       if (cost> 1.) cost =  1.;                << 
764       // compute sint                          << 
765       G4double dum    = 1.-cost;               << 
766       G4double sint   = std::sqrt(dum*(2.-dum) << 
767       G4double phi    = CLHEP::twopi*G4Uniform << 
768       G4double sinPhi = std::sin(phi);         << 
769       G4double cosPhi = std::cos(phi);         << 
770       fTheNewDirection.set(sint*cosPhi,sint*si    690       fTheNewDirection.set(sint*cosPhi,sint*sinPhi,cost);
771     } else if (fIsMultipleSacettring) {        << 691     } else if(fIsMultipleSacettring){
772       // sample multiple scattering               692       // sample multiple scattering
773       SampleMSC(); // fTheZPathLenght, fTheDis    693       SampleMSC(); // fTheZPathLenght, fTheDisplacementVector and fTheNewDirection will be set
774     } // and if single scattering but it was l    694     } // and if single scattering but it was longer => nothing to do
775   } //else { do nothing here but after transpo    695   } //else { do nothing here but after transportation
776   //                                           << 696 
777   return ConvertTrueToGeom(fTheTrueStepLenght,    697   return ConvertTrueToGeom(fTheTrueStepLenght,currentMinimalStep);
778 }                                                 698 }
779                                                   699 
780                                                   700 
781 G4double G4GoudsmitSaundersonMscModel::Compute << 701 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 702 G4double G4GoudsmitSaundersonMscModel::ComputeGeomPathLength(G4double)
                                                   >> 703 {
                                                   >> 704   //
782   // convert true ->geom                          705   // convert true ->geom
783   // It is called from the step limitation Com    706   // It is called from the step limitation ComputeTruePathLengthLimit if
784   // !fIsEverythingWasDone but protect:           707   // !fIsEverythingWasDone but protect:
785   par1 = -1.;                                  << 708   //
786   par2 = par3 = 0.;                            << 709   par1 = -1. ;
                                                   >> 710   par2 = par3 = 0. ;
                                                   >> 711 
787   // if fIsEverythingWasDone = TRUE  => fTheZP    712   // if fIsEverythingWasDone = TRUE  => fTheZPathLenght is already set
788   // so return with the already known value       713   // so return with the already known value
789   // Otherwise:                                   714   // Otherwise:
790   if (!fIsEverythingWasDone) {                 << 715   if(!fIsEverythingWasDone) {
791     // this correction needed to run MSC with  << 716      // this correction needed to run MSC with eIoni and eBrem inactivated
792     // and makes no harm for a normal run      << 717      // and makes no harm for a normal run
793     fTheTrueStepLenght = std::min(fTheTrueStep << 718      fTheTrueStepLenght = std::min(fTheTrueStepLenght,currentRange);
794     //  do the true -> geom transformation     << 719 
795     fTheZPathLenght = fTheTrueStepLenght;      << 720      //  do the true -> geom transformation
796     // z = t for very small true-path-length   << 721      fTheZPathLenght = fTheTrueStepLenght;
797     if (fTheTrueStepLenght<tlimitminfix2) {    << 722 
798       return fTheZPathLenght;                  << 723      // z = t for very small true-path-length
799     }                                          << 724      if(fTheTrueStepLenght < tlimitminfix2) return fTheZPathLenght;
800     G4double tau = fTheTrueStepLenght/fLambda1 << 725 
801     if (tau<=tausmall) {                       << 726      G4double tau = fTheTrueStepLenght/fLambda1;
802       fTheZPathLenght = std::min(fTheTrueStepL << 727 
803     } else  if (fTheTrueStepLenght<currentRang << 728      if (tau <= tausmall) {
804       if (tau<taulim) fTheZPathLenght = fTheTr << 729        fTheZPathLenght = std::min(fTheTrueStepLenght, fLambda1);
805       else            fTheZPathLenght = fLambd << 730      } else  if (fTheTrueStepLenght < currentRange*dtrl) {
806     } else if (currentKinEnergy<mass || fTheTr << 731        if(tau < taulim) fTheZPathLenght = fTheTrueStepLenght*(1.-0.5*tau) ;
807       par1 = 1./currentRange ;     // alpha =1 << 732        else             fTheZPathLenght = fLambda1*(1.-G4Exp(-tau));
808       par2 = 1./(par1*fLambda1) ;  // 1/(alpha << 733      } else if(currentKinEnergy < mass || fTheTrueStepLenght == currentRange)  {
809       par3 = 1.+par2 ;             // 1+1/     << 734        par1 = 1./currentRange ;     // alpha =1/range_init for Ekin<mass
810       if (fTheTrueStepLenght<currentRange) {   << 735        par2 = 1./(par1*fLambda1) ;  // 1/(alphaxlambda01)
811         fTheZPathLenght = 1./(par1*par3) * (1. << 736        par3 = 1.+par2 ;             // 1+1/
812       } else {                                 << 737        if(fTheTrueStepLenght < currentRange) {
813         fTheZPathLenght = 1./(par1*par3);      << 738            fTheZPathLenght = 1./(par1*par3) * (1.-std::pow(1.-par1*fTheTrueStepLenght,par3));
814       }                                        << 739        } else {
                                                   >> 740          fTheZPathLenght = 1./(par1*par3);
                                                   >> 741        }
                                                   >> 742 
815     } else {                                      743     } else {
816       G4double rfin    = std::max(currentRange << 744       G4double rfin = std::max(currentRange-fTheTrueStepLenght, 0.01*currentRange);
817       G4double T1      = GetEnergy(particle,rf << 745       G4double T1 = GetEnergy(particle,rfin,currentCouple);
818       G4double lambda1 = GetTransportMeanFreeP    746       G4double lambda1 = GetTransportMeanFreePathOnly(particle,T1);
819       //                                       << 747 
820       par1 = (fLambda1-lambda1)/(fLambda1*fThe    748       par1 = (fLambda1-lambda1)/(fLambda1*fTheTrueStepLenght);  // alpha
821       par2 = 1./(par1*fLambda1);                  749       par2 = 1./(par1*fLambda1);
822       par3 = 1.+par2 ;                            750       par3 = 1.+par2 ;
823       G4Pow *g4calc = G4Pow::GetInstance();       751       G4Pow *g4calc = G4Pow::GetInstance();
824       fTheZPathLenght = 1./(par1*par3) * (1.-g    752       fTheZPathLenght = 1./(par1*par3) * (1.-g4calc->powA(1.-par1*fTheTrueStepLenght,par3));
825     }                                             753     }
826   }                                               754   }
827   fTheZPathLenght = std::min(fTheZPathLenght,     755   fTheZPathLenght = std::min(fTheZPathLenght, fLambda1);
828   //                                           << 
829   return fTheZPathLenght;                      << 
830 }                                              << 
831                                                   756 
                                                   >> 757  return fTheZPathLenght;
                                                   >> 758 }
832                                                   759 
833 G4double G4GoudsmitSaundersonMscModel::Compute << 760 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 761 G4double G4GoudsmitSaundersonMscModel::ComputeTrueStepLength(G4double geomStepLength)
                                                   >> 762 {
834   // init                                         763   // init
835   fIsEndedUpOnBoundary = false;                   764   fIsEndedUpOnBoundary = false;
                                                   >> 765 
836   // step defined other than transportation       766   // step defined other than transportation
837   if (geomStepLength==fTheZPathLenght) {       << 767   if(geomStepLength == fTheZPathLenght) {
838     return fTheTrueStepLenght;                    768     return fTheTrueStepLenght;
839   }                                               769   }
                                                   >> 770 
840   // else ::                                      771   // else ::
841   // - set the flag that transportation was th    772   // - set the flag that transportation was the winer so DoNothin in DOIT !!
842   // - convert geom -> true by using the mean     773   // - convert geom -> true by using the mean value
843   fIsEndedUpOnBoundary = true; // OR LAST STEP    774   fIsEndedUpOnBoundary = true; // OR LAST STEP
844   fTheZPathLenght      = geomStepLength;       << 775 
                                                   >> 776   fTheZPathLenght = geomStepLength;
                                                   >> 777 
845   // was a short single scattering step           778   // was a short single scattering step
846   if (fIsEverythingWasDone && !fIsMultipleSace << 779   if(fIsEverythingWasDone && !fIsMultipleSacettring) {
847     fTheTrueStepLenght = geomStepLength;          780     fTheTrueStepLenght = geomStepLength;
848     return fTheTrueStepLenght;                    781     return fTheTrueStepLenght;
849   }                                               782   }
                                                   >> 783 
850   // t = z for very small step                    784   // t = z for very small step
851   if (geomStepLength<tlimitminfix2) {          << 785   if(geomStepLength < tlimitminfix2) {
852     fTheTrueStepLenght = geomStepLength;          786     fTheTrueStepLenght = geomStepLength;
853   // recalculation                                787   // recalculation
854   } else {                                        788   } else {
855     G4double tlength = geomStepLength;            789     G4double tlength = geomStepLength;
856     if (geomStepLength>fLambda1*tausmall) {    << 790     if(geomStepLength > fLambda1*tausmall ) {
857       if (par1< 0.) {                          << 791       if(par1 <  0.) {
858         tlength = -fLambda1*G4Log(1.-geomStepL    792         tlength = -fLambda1*G4Log(1.-geomStepLength/fLambda1) ;
859       } else {                                    793       } else {
860         if (par1*par3*geomStepLength<1.) {     << 794        if(par1*par3*geomStepLength < 1.) {
861           G4Pow *g4calc = G4Pow::GetInstance() << 795            G4Pow *g4calc = G4Pow::GetInstance();
862           tlength = (1.-g4calc->powA( 1.-par1* << 796            tlength = (1.-g4calc->powA( 1.-par1*par3*geomStepLength,1./par3))/par1;
863         } else {                                  797         } else {
864           tlength = currentRange;                 798           tlength = currentRange;
865         }                                         799         }
866       }                                           800       }
867       if (tlength<geomStepLength || tlength>fT << 801      if(tlength < geomStepLength)   { tlength = geomStepLength; }
868         tlength = geomStepLength;              << 802      else if(tlength > fTheTrueStepLenght) { tlength = geomStepLength; }
869       }                                        << 
870     }                                             803     }
871     fTheTrueStepLenght = tlength;                 804     fTheTrueStepLenght = tlength;
872   }                                               805   }
873   //                                           << 
874   return fTheTrueStepLenght;                      806   return fTheTrueStepLenght;
875 }                                                 807 }
876                                                   808 
                                                   >> 809 ////////////////////////////////////////////////////////////////////////////////
877 G4ThreeVector&                                    810 G4ThreeVector&
878 G4GoudsmitSaundersonMscModel::SampleScattering    811 G4GoudsmitSaundersonMscModel::SampleScattering(const G4ThreeVector& oldDirection, G4double) {
879   if (steppingAlgorithm==fUseDistanceToBoundar << 812   if(steppingAlgorithm == fUseDistanceToBoundary && fIsEverythingWasDone && fIsSingleScattering){ // ONLY single scattering is done in advance
880     // single scattering was and scattering ha << 813       // single scattering was and scattering happend
881     fTheNewDirection.rotateUz(oldDirection);   << 814       fTheNewDirection.rotateUz(oldDirection);
882     fParticleChange->ProposeMomentumDirection( << 815 //      fTheDisplacementVector.set(0.,0.,0.);
883     return fTheDisplacementVector;             << 816       fParticleChange->ProposeMomentumDirection(fTheNewDirection);
884   } else if (steppingAlgorithm==fUseSafetyPlus << 
885     if (fIsEndedUpOnBoundary) { // do nothing  << 
886       return fTheDisplacementVector;              817       return fTheDisplacementVector;
887     } else if (fIsEverythingWasDone) { // evry << 818   } else if(steppingAlgorithm == fUseSafety) {
888       // check single scattering and see if it << 819       if(fIsEndedUpOnBoundary) {// do nothing
889       if (fIsSingleScattering) {               << 820 //        fTheDisplacementVector.set(0.,0.,0.);
890         fTheNewDirection.rotateUz(oldDirection << 
891         fParticleChange->ProposeMomentumDirect << 
892         return fTheDisplacementVector;            821         return fTheDisplacementVector;
893       }                                        << 822       } else if(fIsEverythingWasDone) {// evrything is done if not optimizations case !!!
894       // check if multiple scattering happened << 823         // check single scattering and see if it happened
895       if (fIsMultipleSacettring && !fIsNoScatt << 824         if(fIsSingleScattering) {
896            fTheNewDirection.rotateUz(oldDirect << 825           fTheNewDirection.rotateUz(oldDirection);
897            fTheDisplacementVector.rotateUz(old << 826   //        fTheDisplacementVector.set(0.,0.,0.);
898            fParticleChange->ProposeMomentumDir << 827           fParticleChange->ProposeMomentumDirection(fTheNewDirection);
899       }                                        << 828           return fTheDisplacementVector;
900       // The only thing that could happen if w << 829         }
901       // is that  single scattering was tried  << 830 
902       // So no displacement and no scattering  << 831         // check if multiple scattering happened and do things only if scattering was really happening
903       return fTheDisplacementVector;           << 832         if(fIsMultipleSacettring && !fIsNoScatteringInMSC){
904     }                                          << 833              fTheNewDirection.rotateUz(oldDirection);
905     //                                         << 834              fTheDisplacementVector.rotateUz(oldDirection);
906     // The only thing that could still happen  << 835              fParticleChange->ProposeMomentumDirection(fTheNewDirection);
907     // optimization branch: so sample MSC angl << 836         }
908   }                                            << 837         // The only thing that could happen if we are here (fUseSafety and fIsEverythingWasDone)
909   //else MSC needs to be done here             << 838         // is that  single scattering was tried but did not win so scattering did not happen.
910   SampleMSC();                                 << 839         // So no displacement and no scattering
911   if (!fIsNoScatteringInMSC) {                 << 840         return fTheDisplacementVector;
912     fTheNewDirection.rotateUz(oldDirection);   << 841      }
913     fParticleChange->ProposeMomentumDirection( << 842      //
914     if (!fIsNoDisplace) {                      << 843      // The only thing that could still happen with fUseSafety is that we are in the
915       fTheDisplacementVector.rotateUz(oldDirec << 844      // optimization branch: so sample MSC angle here (no displacement)
916     }                                          << 
917   }                                               845   }
918   //                                           << 846 
919   return fTheDisplacementVector;               << 847  //else
                                                   >> 848    // MSC needs to be done here
                                                   >> 849    SampleMSC();
                                                   >> 850    if(!fIsNoScatteringInMSC) {
                                                   >> 851       fTheNewDirection.rotateUz(oldDirection);
                                                   >> 852       fParticleChange->ProposeMomentumDirection(fTheNewDirection);
                                                   >> 853       if(!fIsNoDisplace)
                                                   >> 854         fTheDisplacementVector.rotateUz(oldDirection);
                                                   >> 855    }
                                                   >> 856    return fTheDisplacementVector;
                                                   >> 857 }
                                                   >> 858 
                                                   >> 859 
                                                   >> 860 void G4GoudsmitSaundersonMscModel::SingleScattering(G4double &cost, G4double &sint){
                                                   >> 861     G4double rand1 = rndmEngineMod->flat();
                                                   >> 862     // sampling 1-cos(theta)
                                                   >> 863     G4double dum0  = 2.0*fScrA*rand1/(1.0 - rand1 + fScrA);
                                                   >> 864     // add protections
                                                   >> 865     if(dum0 < 0.0)       dum0 = 0.0;
                                                   >> 866     else if(dum0 > 2.0 ) dum0 = 2.0;
                                                   >> 867     // compute cos(theta) and sin(theta)
                                                   >> 868     cost = 1.0 - dum0;
                                                   >> 869     sint = std::sqrt(dum0*(2.0 - dum0));
920 }                                                 870 }
921                                                   871 
922                                                   872 
923 void G4GoudsmitSaundersonMscModel::SampleMSC() << 873 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 874 void G4GoudsmitSaundersonMscModel::SampleMSC(){
924   fIsNoScatteringInMSC = false;                   875   fIsNoScatteringInMSC = false;
925   // kinetic energy is assumed to be in Geant4    876   // kinetic energy is assumed to be in Geant4 internal energy unit which is MeV
926   G4double kineticEnergy = currentKinEnergy;      877   G4double kineticEnergy = currentKinEnergy;
927   //                                           << 878 
                                                   >> 879   ///////////////////////////////////////////
928   // Energy loss correction: 2 version            880   // Energy loss correction: 2 version
929   G4double eloss  = 0.0;                          881   G4double eloss  = 0.0;
930 //  if (fTheTrueStepLenght > currentRange*dtrl    882 //  if (fTheTrueStepLenght > currentRange*dtrl) {
931   eloss = kineticEnergy - GetEnergy(particle,c << 883     eloss = kineticEnergy -
                                                   >> 884       GetEnergy(particle,currentRange-fTheTrueStepLenght,currentCouple);
932 //  } else {                                      885 //  } else {
933 //    eloss = fTheTrueStepLenght*GetDEDX(parti    886 //    eloss = fTheTrueStepLenght*GetDEDX(particle,kineticEnergy,currentCouple);
934 //  }                                             887 //  }
935                                                   888 
                                                   >> 889 
936   G4double tau  = 0.;//    = kineticEnergy/ele    890   G4double tau  = 0.;//    = kineticEnergy/electron_mass_c2; // where kinEnergy is the mean kinetic energy
937   G4double tau2 = 0.;//   = tau*tau;              891   G4double tau2 = 0.;//   = tau*tau;
938   G4double eps0 = 0.;//   = eloss/kineticEnerg    892   G4double eps0 = 0.;//   = eloss/kineticEnergy0; // energy loss fraction to the begin step energy
939   G4double epsm = 0.;//   = eloss/kineticEnerg    893   G4double epsm = 0.;//   = eloss/kineticEnergy;  // energy loss fraction to the mean step energy
940                                                   894 
                                                   >> 895 
941   // - init.                                      896   // - init.
942   G4double efEnergy = kineticEnergy;              897   G4double efEnergy = kineticEnergy;
943   G4double efStep   = fTheTrueStepLenght;         898   G4double efStep   = fTheTrueStepLenght;
944                                                   899 
945   G4double kineticEnergy0 = kineticEnergy;        900   G4double kineticEnergy0 = kineticEnergy;
946   if (gIsUseAccurate) {    // - use accurate e << 901   if(fgIsUseAccurate) {    // - use accurate energy loss correction
947     kineticEnergy  -= 0.5*eloss;  // mean ener << 902      kineticEnergy -= 0.5*eloss;  // mean energy along the full step
948     // other parameters for energy loss correc << 903 
949     tau             = kineticEnergy/electron_m << 904      // other parameters for energy loss corrections
950     tau2            = tau*tau;                 << 905      tau    = kineticEnergy/electron_mass_c2; // where kinEnergy is the mean kinetic energy
951     eps0            = eloss/kineticEnergy0; // << 906      tau2   = tau*tau;
952     epsm            = eloss/kineticEnergy;  // << 907      eps0   = eloss/kineticEnergy0; // energy loss fraction to the begin step energy
953                                                << 908      epsm   = eloss/kineticEnergy;  // energy loss fraction to the mean step energy
954     efEnergy        = kineticEnergy * (1.-epsm << 909 
955     G4double dum    = 0.166666*(4.+tau*(6.+tau << 910       efEnergy       = kineticEnergy * (1. - epsm*epsm*(6.+10.*tau+5.*tau2)/(24.*tau2+48.*tau+72.));
956     efStep          = fTheTrueStepLenght*(1.-d << 911       G4double dum  = 0.166666*(4.+tau*(6.+tau*(7.+tau*(4.+tau))))*
                                                   >> 912                      (epsm/((tau+1.)*(tau+2.)))*(epsm/((tau+1.)*(tau+2.)));
                                                   >> 913       efStep =fTheTrueStepLenght*(1.-dum);
957   } else {                              // - t    914   } else {                              // - take only mean energy
958     kineticEnergy  -= 0.5*eloss;  // mean ener << 915       kineticEnergy -= 0.5*eloss;  // mean energy along the full step
959     efEnergy        = kineticEnergy;           << 916       efEnergy       = kineticEnergy;
960     G4double factor = 1./(1.+0.9784671*kinetic << 917       G4double factor = 1./(1. + 0.9784671*kineticEnergy); //0.9784671 = 1/(2*rm)
961     eps0            = eloss/kineticEnergy0;    << 918       eps0= eloss/kineticEnergy0;
962     epsm            = eps0/(1.-0.5*eps0);      << 919       epsm= eps0/(1.-0.5*eps0);
963     G4double temp   = 0.3*(1 -factor*(1.-0.333 << 920       G4double temp   = 0.3*(1. - factor*(1. - 0.333333*factor))*eps0*eps0;
964     efStep          = fTheTrueStepLenght*(1.+t << 921       efStep = fTheTrueStepLenght*(1. + temp);
965   }                                               922   }
966   //                                           << 923 
967   // compute elastic mfp, first transport mfp, << 924   ///////////////////////////////////////////
968   // if it was requested by the user)          << 925   // Compute elastic mfp, first transport mfp, screening parameter, and G1
969   fLambda1 = GetTransportMeanFreePath(particle << 926   fLambda1 = GetTransportMeanFreePath(particle,efEnergy);
970   // s/lambda_el                               << 927 
971   G4double lambdan=0.;                            928   G4double lambdan=0.;
972   if (fLambda0>0.0) {                          << 929 
973     lambdan=efStep/fLambda0;                   << 930   if(fLambda0>0.0) { lambdan=efStep/fLambda0; }
974   }                                            << 931   if(lambdan<=1.0e-12) {
975   if (lambdan<=1.0e-12) {                      << 932       if(fIsEverythingWasDone)
976       if (fIsEverythingWasDone) {              << 
977         fTheZPathLenght = fTheTrueStepLenght;     933         fTheZPathLenght = fTheTrueStepLenght;
978       }                                        << 
979     fIsNoScatteringInMSC = true;                  934     fIsNoScatteringInMSC = true;
980     return;                                       935     return;
981   }                                               936   }
982   // first moment: 2.* lambdan *scrA*((1.+scrA << 937 
983   G4double Qn1 = lambdan *fG1;                 << 938   // correction from neglected term 1+A (only for Moliere parameter)
984   // sample scattering angles                  << 939   if(!fIsUsePWATotalXsecData)  
                                                   >> 940     lambdan = lambdan/(1.+fScrA);
                                                   >> 941 
                                                   >> 942   G4double Qn1 = lambdan *fG1;//2.* lambdan *scrA*((1.+scrA)*log(1.+1./scrA)-1.);
                                                   >> 943 
                                                   >> 944   /////////////////////////////////////////////////////////////////////////////
                                                   >> 945   // Sample scattering angles
985   // new direction, relative to the orriginal     946   // new direction, relative to the orriginal one is in {uss,vss,wss}
986   G4double cosTheta1 = 1.0, sinTheta1 = 0.0, c << 947   G4double cosTheta1 =1.0,sinTheta1 =0.0, cosTheta2 =1.0, sinTheta2 =0.0;
987   G4double cosPhi1   = 1.0, sinPhi1   = 0.0, c << 948   G4double cosPhi1=1.0,sinPhi1=0.0, cosPhi2 =1.0, sinPhi2 =0.0;
988   G4double uss       = 0.0, vss       = 0.0, w << 949   G4double uss=0.0,vss=0.0,wss=1.0,x_coord=0.0,y_coord=0.0,z_coord=1.0;
989   G4double x_coord   = 0.0, y_coord   = 0.0, z << 950   G4double u2=0.0,v2=0.0;
990   G4double u2 = 0.0, v2 = 0.0;                 << 951 
991   // if we are above the upper grid limit with    952   // if we are above the upper grid limit with lambdaxG1=true-length/first-trans-mfp
992   // => izotropic distribution: lambG1_max =7.    953   // => izotropic distribution: lambG1_max =7.992 but set it to 7
993   if (0.5*Qn1 > 7.0){                          << 954   if(0.5*Qn1 > 7.0){
994     cosTheta1 = 1.-2.*G4UniformRand();         << 955     G4double vrand[2];
                                                   >> 956     rndmEngineMod->flatArray(2,vrand); //get 2 random number
                                                   >> 957     cosTheta1 = 1.-2.*vrand[0];
995     sinTheta1 = std::sqrt((1.-cosTheta1)*(1.+c    958     sinTheta1 = std::sqrt((1.-cosTheta1)*(1.+cosTheta1));
996     cosTheta2 = 1.-2.*G4UniformRand();         << 959     cosTheta2 = 1.-2.*vrand[1];
997     sinTheta2 = std::sqrt((1.-cosTheta2)*(1.+c    960     sinTheta2 = std::sqrt((1.-cosTheta2)*(1.+cosTheta2));
998   } else {                                        961   } else {
999      // sample 2 scattering cost1, sint1, cost    962      // sample 2 scattering cost1, sint1, cost2 and sint2 for half path
1000      G4double lekin  = G4Log(efEnergy);       << 963      fgGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta1, sinTheta1);
1001      G4double pt2    = efEnergy*(efEnergy+2.0 << 964      fgGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta2, sinTheta2);
1002      G4double beta2  = pt2/(pt2+CLHEP::electr << 965      if(cosTheta1 + cosTheta2 == 2.) { // no scattering happened
1003      // backup GS angular dtr pointer (kineti << 966         if(fIsEverythingWasDone)
1004      // if the first was an msc sampling (the << 
1005      G4GoudsmitSaundersonTable::GSMSCAngularD << 
1006      G4int mcEkinIdx    = -1;                 << 
1007      G4int mcDeltIdx    = -1;                 << 
1008      G4double transfPar = 0.;                 << 
1009      G4bool isMsc = fGSTable->Sampling(0.5*la << 
1010                                        curren << 
1011                                        true); << 
1012      fGSTable->Sampling(0.5*lambdan, 0.5*Qn1, << 
1013                         currentMaterialIndex, << 
1014      if (cosTheta1+cosTheta2==2.) { // no sca << 
1015         if (fIsEverythingWasDone)             << 
1016            fTheZPathLenght = fTheTrueStepLeng    967            fTheZPathLenght = fTheTrueStepLenght;
1017         fIsNoScatteringInMSC = true;             968         fIsNoScatteringInMSC = true;
1018         return;                                  969         return;
1019      }                                           970      }
1020   }                                              971   }
1021   // sample 2 azimuthal angles                   972   // sample 2 azimuthal angles
1022   G4double phi1 = CLHEP::twopi*G4UniformRand( << 973   G4double vrand[2];
                                                   >> 974   rndmEngineMod->flatArray(2,vrand); //get 2 random number
                                                   >> 975   G4double phi1 = CLHEP::twopi*vrand[0];
1023   sinPhi1 = std::sin(phi1);                      976   sinPhi1 = std::sin(phi1);
1024   cosPhi1 = std::cos(phi1);                      977   cosPhi1 = std::cos(phi1);
1025   G4double phi2 = CLHEP::twopi*G4UniformRand( << 978   G4double phi2 = CLHEP::twopi*vrand[1];
1026   sinPhi2 = std::sin(phi2);                      979   sinPhi2 = std::sin(phi2);
1027   cosPhi2 = std::cos(phi2);                      980   cosPhi2 = std::cos(phi2);
1028                                                  981 
1029   // compute final direction realtive to z-di    982   // compute final direction realtive to z-dir
1030   u2  = sinTheta2*cosPhi2;                       983   u2  = sinTheta2*cosPhi2;
1031   v2  = sinTheta2*sinPhi2;                       984   v2  = sinTheta2*sinPhi2;
1032   G4double u2p = cosTheta1*u2 + sinTheta1*cos    985   G4double u2p = cosTheta1*u2 + sinTheta1*cosTheta2;
1033   uss  = u2p*cosPhi1 - v2*sinPhi1;               986   uss  = u2p*cosPhi1 - v2*sinPhi1;
1034   vss  = u2p*sinPhi1 + v2*cosPhi1;               987   vss  = u2p*sinPhi1 + v2*cosPhi1;
1035   wss  = cosTheta1*cosTheta2 - sinTheta1*u2;     988   wss  = cosTheta1*cosTheta2 - sinTheta1*u2;
1036                                                  989 
1037   // set new direction (is scattering frame)  << 990   ////////////////////////////////////////////////////////////////////
1038   fTheNewDirection.set(uss,vss,wss);             991   fTheNewDirection.set(uss,vss,wss);
1039                                                  992 
1040   // set the fTheZPathLenght if we don't samp    993   // set the fTheZPathLenght if we don't sample displacement and
1041   // we should do everything at the step-limi    994   // we should do everything at the step-limit-phase before we return
1042   if(fIsNoDisplace && fIsEverythingWasDone)      995   if(fIsNoDisplace && fIsEverythingWasDone)
1043     fTheZPathLenght = fTheTrueStepLenght;        996     fTheZPathLenght = fTheTrueStepLenght;
1044                                                  997 
1045   // in optimized-mode if the current-safety     998   // in optimized-mode if the current-safety > current-range we do not use dispalcement
1046   if(fIsNoDisplace)                              999   if(fIsNoDisplace)
1047     return;                                      1000     return;
1048                                                  1001 
1049   ///////////////////////////////////////////    1002   //////////////////////////////////////////////////////////////////////
1050   // Compute final position                      1003   // Compute final position
1051   Qn1 *=  fMCtoQ1;                            << 1004   if(fgIsUseAccurate) {
1052   if (gIsUseAccurate) {                       << 
1053      // correction parameter                     1005      // correction parameter
1054      G4double par =1.;                           1006      G4double par =1.;
1055      if(Qn1<0.7) par = 1.;                       1007      if(Qn1<0.7) par = 1.;
1056      else if (Qn1<7.0) par = -0.031376*Qn1+1.    1008      else if (Qn1<7.0) par = -0.031376*Qn1+1.01356;
1057      else par = 0.79;                            1009      else par = 0.79;
1058                                                  1010 
1059      // Moments with energy loss correction      1011      // Moments with energy loss correction
1060      // --first the uncorrected (for energy l    1012      // --first the uncorrected (for energy loss) values of gamma, eta, a1=a2=0.5*(1-eta), delta
1061      // gamma = G_2/G_1 based on G2 computed     1013      // gamma = G_2/G_1 based on G2 computed from A by using the Wentzel DCS form of G2
1062      G4double loga   = G4Log(1.0+1.0/fScrA);     1014      G4double loga   = G4Log(1.0+1.0/fScrA);
1063      G4double gamma  = 6.0*fScrA*(1.0 + fScrA    1015      G4double gamma  = 6.0*fScrA*(1.0 + fScrA)*(loga*(1.0 + 2.0*fScrA) - 2.0)/fG1;
1064      gamma *= fMCtoG2PerG1;                   << 
1065      // sample eta from p(eta)=2*eta i.e. P(e    1016      // sample eta from p(eta)=2*eta i.e. P(eta) = eta_square ;-> P(eta) = rand --> eta = sqrt(rand)
1066      G4double eta    = std::sqrt(G4UniformRan << 1017      G4double eta    = std::sqrt(rndmEngineMod->flat());
1067      G4double eta1   = 0.5*(1 - eta);  // use    1018      G4double eta1   = 0.5*(1 - eta);  // used  more than once
1068      // 0.5 +sqrt(6)/6 = 0.9082483;              1019      // 0.5 +sqrt(6)/6 = 0.9082483;
1069      // 1/(4*sqrt(6))  = 0.1020621;              1020      // 1/(4*sqrt(6))  = 0.1020621;
1070      // (4-sqrt(6)/(24*sqrt(6))) = 0.02637471    1021      // (4-sqrt(6)/(24*sqrt(6))) = 0.026374715
1071      // delta = 0.9082483-(0.1020621-0.026374    1022      // delta = 0.9082483-(0.1020621-0.0263747*gamma)*Qn1 without energy loss cor.
1072      G4double delta  = 0.9082483-(0.1020621-0    1023      G4double delta  = 0.9082483-(0.1020621-0.0263747*gamma)*Qn1;
1073                                                  1024 
1074      // compute alpha1 and alpha2 for energy     1025      // compute alpha1 and alpha2 for energy loss correction
1075      G4double temp1 = 2.0 + tau;                 1026      G4double temp1 = 2.0 + tau;
1076      G4double temp  = (2.0+tau*temp1)/((tau+1    1027      G4double temp  = (2.0+tau*temp1)/((tau+1.0)*temp1);
1077      //Take logarithmic dependence               1028      //Take logarithmic dependence
1078      temp = temp - (tau+1.0)/((tau+2.0)*(loga    1029      temp = temp - (tau+1.0)/((tau+2.0)*(loga*(1.0+fScrA)-1.0));
1079      temp = temp * epsm;                         1030      temp = temp * epsm;
1080      temp1 = 1.0 - temp;                         1031      temp1 = 1.0 - temp;
1081      delta = delta + 0.40824829*(eps0*(tau+1.    1032      delta = delta + 0.40824829*(eps0*(tau+1.0)/((tau+2.0)*
1082              (loga*(1.0+fScrA)-1.0)*(loga*(1.    1033              (loga*(1.0+fScrA)-1.0)*(loga*(1.0+2.0*fScrA)-2.0)) - 0.25*temp*temp);
1083      G4double b      = eta*delta;                1034      G4double b      = eta*delta;
1084      G4double c      = eta*(1.0-delta);          1035      G4double c      = eta*(1.0-delta);
1085                                                  1036 
1086      //Calculate transport direction cosines:    1037      //Calculate transport direction cosines:
1087      // ut,vt,wt is the final position divide    1038      // ut,vt,wt is the final position divided by the true step length
1088      G4double w1v2 = cosTheta1*v2;               1039      G4double w1v2 = cosTheta1*v2;
1089      G4double ut   = b*sinTheta1*cosPhi1 + c*    1040      G4double ut   = b*sinTheta1*cosPhi1 + c*(cosPhi1*u2 - sinPhi1*w1v2) + eta1*uss*temp1;
1090      G4double vt   = b*sinTheta1*sinPhi1 + c*    1041      G4double vt   = b*sinTheta1*sinPhi1 + c*(sinPhi1*u2 + cosPhi1*w1v2) + eta1*vss*temp1;
1091      G4double wt   = eta1*(1+temp) +       b*    1042      G4double wt   = eta1*(1+temp) +       b*cosTheta1 +  c*cosTheta2    + eta1*wss*temp1;
1092                                                  1043 
1093      // long step correction                     1044      // long step correction
1094      ut *=par;                                   1045      ut *=par;
1095      vt *=par;                                   1046      vt *=par;
1096      wt *=par;                                   1047      wt *=par;
1097                                                  1048 
1098      // final position relative to the pre-st    1049      // final position relative to the pre-step point in the scattering frame
1099      // ut = x_f/s so needs to multiply by s     1050      // ut = x_f/s so needs to multiply by s
1100      x_coord = ut*fTheTrueStepLenght;            1051      x_coord = ut*fTheTrueStepLenght;
1101      y_coord = vt*fTheTrueStepLenght;            1052      y_coord = vt*fTheTrueStepLenght;
1102      z_coord = wt*fTheTrueStepLenght;            1053      z_coord = wt*fTheTrueStepLenght;
1103                                                  1054 
1104      if(fIsEverythingWasDone){                   1055      if(fIsEverythingWasDone){
1105        // We sample in the step limit so set     1056        // We sample in the step limit so set fTheZPathLenght = transportDistance
1106        // and lateral displacement (x_coord,y    1057        // and lateral displacement (x_coord,y_coord,z_coord-transportDistance)
1107        //Calculate transport distance            1058        //Calculate transport distance
1108        G4double transportDistance  = std::sqr    1059        G4double transportDistance  = std::sqrt(x_coord*x_coord+y_coord*y_coord+z_coord*z_coord);
1109        // protection                             1060        // protection
1110        if(transportDistance>fTheTrueStepLengh    1061        if(transportDistance>fTheTrueStepLenght)
1111           transportDistance = fTheTrueStepLen    1062           transportDistance = fTheTrueStepLenght;
1112        fTheZPathLenght = transportDistance;      1063        fTheZPathLenght = transportDistance;
1113      }                                           1064      }
1114      // else:: we sample in the DoIt so          1065      // else:: we sample in the DoIt so
1115      //       the fTheZPathLenght was already    1066      //       the fTheZPathLenght was already set and was taken as transport along zet
1116      fTheDisplacementVector.set(x_coord,y_coo    1067      fTheDisplacementVector.set(x_coord,y_coord,z_coord-fTheZPathLenght);
1117   } else {                                       1068   } else {
1118      // compute zz = <z>/tPathLength             1069      // compute zz = <z>/tPathLength
1119      // s -> true-path-length                    1070      // s -> true-path-length
1120      // z -> geom-path-length:: when PRESTA i    1071      // z -> geom-path-length:: when PRESTA is used z =(def.) <z>
1121      // r -> lateral displacement = s/2 sin(t    1072      // r -> lateral displacement = s/2 sin(theta)  => x_f = r cos(phi); y_f = r sin(phi)
1122      G4double zz = 0.0;                          1073      G4double zz = 0.0;
1123      if(fIsEverythingWasDone){                   1074      if(fIsEverythingWasDone){
1124         // We sample in the step limit so set    1075         // We sample in the step limit so set fTheZPathLenght = transportDistance
1125         // and lateral displacement (x_coord,    1076         // and lateral displacement (x_coord,y_coord,z_coord-transportDistance)
1126         if(Qn1<0.1) { // use 3-order Taylor a    1077         if(Qn1<0.1) { // use 3-order Taylor approximation of (1-exp(-x))/x around x=0
1127           zz = 1.0 - Qn1*(0.5 - Qn1*(0.166666    1078           zz = 1.0 - Qn1*(0.5 - Qn1*(0.166666667 - 0.041666667*Qn1)); // 1/6 =0.166..7 ; 1/24=0.041..
1128         } else {                                 1079         } else {
1129           zz = (1.-G4Exp(-Qn1))/Qn1;             1080           zz = (1.-G4Exp(-Qn1))/Qn1;
1130         }                                        1081         }
1131      } else {                                    1082      } else {
1132         // we sample in the DoIt so              1083         // we sample in the DoIt so
1133         // the fTheZPathLenght was already se    1084         // the fTheZPathLenght was already set and was taken as transport along zet
1134         zz = fTheZPathLenght/fTheTrueStepLeng    1085         zz = fTheZPathLenght/fTheTrueStepLenght;
1135      }                                           1086      }
1136                                                  1087 
1137      G4double rr = (1.-zz*zz)/(1.-wss*wss); /    1088      G4double rr = (1.-zz*zz)/(1.-wss*wss); // s^2 >= <z>^2+r^2  :: where r^2 = s^2/4 sin^2(theta)
1138      if(rr >= 0.25) rr = 0.25;            //     1089      if(rr >= 0.25) rr = 0.25;            // (1-<z>^2/s^2)/sin^2(theta) >= r^2/(s^2 sin^2(theta)) = 1/4 must hold
1139      G4double rperp = fTheTrueStepLenght*std:    1090      G4double rperp = fTheTrueStepLenght*std::sqrt(rr);  // this is r/sint
1140      x_coord  = rperp*uss;                       1091      x_coord  = rperp*uss;
1141      y_coord  = rperp*vss;                       1092      y_coord  = rperp*vss;
1142      z_coord  = zz*fTheTrueStepLenght;           1093      z_coord  = zz*fTheTrueStepLenght;
1143                                                  1094 
1144      if(fIsEverythingWasDone){                   1095      if(fIsEverythingWasDone){
1145        G4double transportDistance = std::sqrt    1096        G4double transportDistance = std::sqrt(x_coord*x_coord + y_coord*y_coord + z_coord*z_coord);
1146        fTheZPathLenght = transportDistance;      1097        fTheZPathLenght = transportDistance;
1147      }                                           1098      }
1148                                                  1099 
1149      fTheDisplacementVector.set(x_coord,y_coo    1100      fTheDisplacementVector.set(x_coord,y_coord,z_coord- fTheZPathLenght);
1150    }                                             1101    }
1151 }                                                1102 }
                                                   >> 1103 
                                                   >> 1104 /*
                                                   >> 1105 ////////////////////////////////////////////////////////////////////////////////
                                                   >> 1106 void G4GoudsmitSaundersonMscModel::SampleMSC(){
                                                   >> 1107   fIsNoScatteringInMSC = false;
                                                   >> 1108   // kinetic energy is assumed to be in Geant4 internal energy unit which is MeV
                                                   >> 1109   G4double kineticEnergy = currentKinEnergy;
                                                   >> 1110 
                                                   >> 1111   ///////////////////////////////////////////
                                                   >> 1112   // Energy loss correction: 2 versions
                                                   >> 1113   G4double eloss  = 0.0;
                                                   >> 1114 //  if (fTheTrueStepLenght > currentRange*dtrl) {
                                                   >> 1115     eloss = kineticEnergy -
                                                   >> 1116       GetEnergy(particle,currentRange-fTheTrueStepLenght,currentCouple);
                                                   >> 1117 //  } else {
                                                   >> 1118 //    eloss = fTheTrueStepLenght*GetDEDX(particle,kineticEnergy,currentCouple);
                                                   >> 1119 //  }
                                                   >> 1120 //eloss*=2.;
                                                   >> 1121 
                                                   >> 1122   G4double tau  = 0.;//    = kineticEnergy/electron_mass_c2; // where kinEnergy is the mean kinetic energy
                                                   >> 1123   G4double tau2 = 0.;//   = tau*tau;
                                                   >> 1124   G4double eps0 = 0.;//   = eloss/kineticEnergy0; // energy loss fraction to the begin step energy
                                                   >> 1125   G4double epsm = 0.;//   = eloss/kineticEnergy;  // energy loss fraction to the mean step energy
                                                   >> 1126 
                                                   >> 1127 
                                                   >> 1128   // - init.
                                                   >> 1129   G4double efEnergy = kineticEnergy;
                                                   >> 1130   G4double efStep   = fTheTrueStepLenght;
                                                   >> 1131 
                                                   >> 1132   G4double kineticEnergy0 = kineticEnergy;
                                                   >> 1133   if(fgIsUseAccurate) {    // - use accurate energy loss correction
                                                   >> 1134      kineticEnergy -= 0.5*eloss;  // mean energy along the full step
                                                   >> 1135 
                                                   >> 1136      // other parameters for energy loss corrections
                                                   >> 1137      tau    = kineticEnergy/electron_mass_c2; // where kinEnergy is the mean kinetic energy
                                                   >> 1138      tau2   = tau*tau;
                                                   >> 1139      eps0   = eloss/kineticEnergy0; // energy loss fraction to the begin step energy
                                                   >> 1140      epsm   = eloss/kineticEnergy;  // energy loss fraction to the mean step energy
                                                   >> 1141 
                                                   >> 1142 
                                                   >> 1143 //     efEnergy = kineticEnergy0 * ( 1.0 - 0.5*eps0 - eps0*eps0/(12.0*(2.0-eps0))* ( (5.*tau2 +10.*tau +6.)/( (tau+1.)*(tau+2.) )  )  );
                                                   >> 1144 //EGSnrc
                                                   >> 1145 efEnergy       = kineticEnergy * (1. - epsm*epsm*(6.+10.*tau+5.*tau2)/(24.*tau2+48.*tau+72.));
                                                   >> 1146 
                                                   >> 1147      // the real efStep will be s*(1-efStep)
                                                   >> 1148   //  G4double efStep    = 0.166666*epsilon*epsilonp*(tau2*tau2+4.0*tau2*tau+7.0*tau2+6.0*tau+4.0)/((tau2+3.0*tau+2)2);
                                                   >> 1149 
                                                   >> 1150 //     efStep    = 0.166666*eps0*epsm*(4.0+tau*(6.0+tau*(7.0+tau*(4.0+tau))));
                                                   >> 1151 //     efStep            /= ((tau2+3.0*tau+2)*(tau2+3.0*tau+2));
                                                   >> 1152 //     efStep             = fTheTrueStepLenght*(1.0-efStep);
                                                   >> 1153 
                                                   >> 1154 
                                                   >> 1155 //      efStep = (1.-eps0*eps0/(3.*(2.-eps0))*  (tau2*tau2 + 4.*tau2*tau + 7.*tau2 +6.*tau +4.)/( ((tau+1.)*(tau+2.))*((tau+1.)*(tau+2.)) ) );
                                                   >> 1156 //      efStep *=fTheTrueStepLenght;
                                                   >> 1157 // EGSnrc
                                                   >> 1158 G4double dum  = 0.166666*(4.+tau*(6.+tau*(7.+tau*(4.+tau))))*
                                                   >> 1159                 (epsm/((tau+1.)*(tau+2.)))*(epsm/((tau+1.)*(tau+2.)));
                                                   >> 1160          efStep =fTheTrueStepLenght*(1.-dum);
                                                   >> 1161   } else {                              // - take only mean energy
                                                   >> 1162       kineticEnergy -= 0.5*eloss;  // mean energy along the full step
                                                   >> 1163       efEnergy       = kineticEnergy;
                                                   >> 1164       //Account for energy loss in the MS distribution
                                                   >> 1165       G4double factor = 1./(1. + 0.9784671*kineticEnergy); //0.9784671 = 1/(2*rm)
                                                   >> 1166       eps0= eloss/kineticEnergy0;
                                                   >> 1167       epsm= eps0/(1.-0.5*eps0);
                                                   >> 1168       G4double temp   = 0.3*(1. - factor*(1. - 0.333333*factor))*eps0*eps0;
                                                   >> 1169       efStep = fTheTrueStepLenght*(1. + temp);
                                                   >> 1170   }
                                                   >> 1171   /////////////////////////////////////////////////////////////////////////
                                                   >> 1172 //efEnergy = kineticEnergy0;
                                                   >> 1173 //efStep   = fTheTrueStepLenght;
                                                   >> 1174 //eps0 =0.;
                                                   >> 1175 //epsm =0.;
                                                   >> 1176   ///////////////////////////////////////////
                                                   >> 1177   // Compute elastic mfp, first transport mfp, screening parameter, and G1
                                                   >> 1178   fLambda1 = GetTransportMeanFreePath(particle,efEnergy);
                                                   >> 1179 
                                                   >> 1180   G4double lambdan=0.;
                                                   >> 1181 
                                                   >> 1182   if(fLambda0>0.0) { lambdan=efStep/fLambda0; }
                                                   >> 1183   if(lambdan<=1.0e-12) {
                                                   >> 1184       if(fIsEverythingWasDone)
                                                   >> 1185         fTheZPathLenght = fTheTrueStepLenght;
                                                   >> 1186     fIsNoScatteringInMSC = true;
                                                   >> 1187     return;
                                                   >> 1188   }
                                                   >> 1189 
                                                   >> 1190 // correction from neglected term 1+A
                                                   >> 1191   lambdan = lambdan/(1.+fScrA);
                                                   >> 1192 
                                                   >> 1193   G4double Qn1 = lambdan *fG1;//2.* lambdan *scrA*((1.+scrA)*log(1.+1./scrA)-1.);
                                                   >> 1194 
                                                   >> 1195 //if(Qn1>0.5 && !fIsNoDisplace){
                                                   >> 1196   //G4cout<<"  Qn1 = "<<Qn1<<G4endl;
                                                   >> 1197 //}
                                                   >> 1198 
                                                   >> 1199   /////////////////////////////////////////////////////////////////////////////
                                                   >> 1200   // Sample scattering angles
                                                   >> 1201   // new direction, relative to the orriginal one is in {us,vs,ws}
                                                   >> 1202   G4double cosTheta1 =1.0,sinTheta1 =0.0, cosTheta2 =1.0, sinTheta2 =0.0;
                                                   >> 1203   G4double cosPhi1=1.0,sinPhi1=0.0, cosPhi2 =1.0, sinPhi2 =0.0;
                                                   >> 1204   G4double us=0.0,vs=0.0,ws=1.0,x_coord=0.0,y_coord=0.0,z_coord=1.0;
                                                   >> 1205   G4double u2=0.0,v2=0.0;
                                                   >> 1206 
                                                   >> 1207   // if we are above the upper grid limit with lambdaxG1=true-length/first-trans-mfp
                                                   >> 1208   // => izotropic distribution: lambG1_max =7.992 but set it to 7
                                                   >> 1209   if(0.5*Qn1 > 7.0){
                                                   >> 1210     G4double vrand[2];
                                                   >> 1211     rndmEngineMod->flatArray(2,vrand); //get 2 random number
                                                   >> 1212     cosTheta1 = 1.-2.*vrand[0];
                                                   >> 1213     sinTheta1 = std::sqrt((1.-cosTheta1)*(1.+cosTheta1));
                                                   >> 1214     cosTheta2 = 1.-2.*vrand[1];
                                                   >> 1215     sinTheta2 = std::sqrt((1.-cosTheta2)*(1.+cosTheta2));
                                                   >> 1216   } else {
                                                   >> 1217      // sample 2 scattering cost1, sint1, cost2 and sint2 for half path
                                                   >> 1218      fgGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta1, sinTheta1);
                                                   >> 1219      fgGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta2, sinTheta2);
                                                   >> 1220      if(cosTheta1 + cosTheta2 == 2.) { // no scattering happened
                                                   >> 1221         if(fIsEverythingWasDone)
                                                   >> 1222            fTheZPathLenght = fTheTrueStepLenght;
                                                   >> 1223         fIsNoScatteringInMSC = true;
                                                   >> 1224         return;
                                                   >> 1225      }
                                                   >> 1226   }
                                                   >> 1227   // sample 2 azimuthal angles
                                                   >> 1228   G4double vrand[2];
                                                   >> 1229   rndmEngineMod->flatArray(2,vrand); //get 2 random number
                                                   >> 1230   G4double phi1 = CLHEP::twopi*vrand[0];
                                                   >> 1231   sinPhi1 = std::sin(phi1);
                                                   >> 1232   cosPhi1 = std::cos(phi1);
                                                   >> 1233   G4double phi2 = CLHEP::twopi*vrand[1];
                                                   >> 1234   sinPhi2 = std::sin(phi2);
                                                   >> 1235   cosPhi2 = std::cos(phi2);
                                                   >> 1236 
                                                   >> 1237   // compute final direction realtive to z-dir
                                                   >> 1238   u2  = sinTheta2*cosPhi2;
                                                   >> 1239   v2  = sinTheta2*sinPhi2;
                                                   >> 1240   G4double u2p = cosTheta1*u2 + sinTheta1*cosTheta2;
                                                   >> 1241   us  = u2p*cosPhi1 - v2*sinPhi1;
                                                   >> 1242   vs  = u2p*sinPhi1 + v2*cosPhi1;
                                                   >> 1243   ws  = cosTheta1*cosTheta2 - sinTheta1*u2;
                                                   >> 1244 
                                                   >> 1245   ////////////////////////////////////////////////////////////////////
                                                   >> 1246   fTheNewDirection.set(us,vs,ws);
                                                   >> 1247 
                                                   >> 1248   // set the fTheZPathLenght if we don't sample displacement and
                                                   >> 1249   // we should do everything at the step-limit-phase before we return
                                                   >> 1250   if(fIsNoDisplace && fIsEverythingWasDone)
                                                   >> 1251     fTheZPathLenght = fTheTrueStepLenght;
                                                   >> 1252 
                                                   >> 1253   // in optimized-mode if the current-safety > current-range we do not use dispalcement
                                                   >> 1254   if(fIsNoDisplace)
                                                   >> 1255     return;
                                                   >> 1256 
                                                   >> 1257   //////////////////////////////////////////////////////////////////////
                                                   >> 1258   // Compute final position
                                                   >> 1259   if(fgIsUseAccurate) {
                                                   >> 1260     // correction parameters
                                                   >> 1261 
                                                   >> 1262     G4double par =1.;
                                                   >> 1263     if(Qn1<0.7) par = 1.;
                                                   >> 1264     else if (Qn1<7.0) par = -0.031376*Qn1+1.01356;
                                                   >> 1265     else par = 0.79;
                                                   >> 1266 
                                                   >> 1267     //
                                                   >> 1268     // Compute elastic mfp, first transport mfp, screening parameter, and G1
                                                   >> 1269     // for the initial energy
                                                   >> 1270 //!!!
                                                   >> 1271 //1    fLambda1 = GetTransportMeanFreePath(particle,currentKinEnergy);
                                                   >> 1272 
                                                   >> 1273      // Moments with energy loss correction
                                                   >> 1274      // --first the uncorrected (for energy loss) values of gamma, eta, a1=a2=0.5*(1-eta), delta
                                                   >> 1275      // gamma = G_2/G_1 based on G2 computed from A by using the Wentzel DCS form of G2
                                                   >> 1276      G4double loga   = G4Log(1.0+1.0/fScrA);
                                                   >> 1277      G4double gamma  = 6.0*fScrA*(1.0 + fScrA)*(loga*(1.0 + 2.0*fScrA) - 2.0)/fG1;
                                                   >> 1278      // sample eta from p(eta)=2*eta i.e. P(eta) = eta_square ;-> P(eta) = rand --> eta = sqrt(rand)
                                                   >> 1279      G4double eta    = std::sqrt(rndmEngineMod->flat());
                                                   >> 1280      G4double eta1   = 0.5*(1 - eta);  // used  more than once
                                                   >> 1281      // 0.5 +sqrt(6)/6 = 0.9082483;
                                                   >> 1282      // 1/(4*sqrt(6))  = 0.1020621;
                                                   >> 1283      // (4-sqrt(6)/(24*sqrt(6))) = 0.026374715
                                                   >> 1284      // delta = 0.9082483-(0.1020621-0.0263747*gamma)*Qn1 without energy loss cor.
                                                   >> 1285 //!!!
                                                   >> 1286 //     Qn1=fTheTrueStepLenght/fLambda0*fG1; // without energy loss
                                                   >> 1287      G4double delta  = 0.9082483-(0.1020621-0.0263747*gamma)*Qn1;
                                                   >> 1288 
                                                   >> 1289      // compute alpha1 and alpha2 for energy loss correction
                                                   >> 1290      G4double temp1 = 2.0 + tau;
                                                   >> 1291      G4double temp  = (2.0+tau*temp1)/((tau+1.0)*temp1);
                                                   >> 1292      //Take logarithmic dependence
                                                   >> 1293      temp = temp - (tau+1.0)/((tau+2.0)*(loga*(1.0+fScrA)-1.0));
                                                   >> 1294      temp = temp * epsm;
                                                   >> 1295      temp1 = 1.0 - temp;
                                                   >> 1296      delta = delta + 0.40824829*(eps0*(tau+1.0)/((tau+2.0)*
                                                   >> 1297              (loga*(1.0+fScrA)-1.0)*(loga*(1.0+2.0*fScrA)-2.0)) - 0.25*temp*temp);
                                                   >> 1298      G4double b      = eta*delta;
                                                   >> 1299      G4double c      = eta*(1.0-delta);
                                                   >> 1300 
                                                   >> 1301      //Calculate transport direction cosines:
                                                   >> 1302      // ut,vt,wt is the final position divided by the true step length
                                                   >> 1303      G4double w1v2 = cosTheta1*v2;
                                                   >> 1304      G4double ut   = b*sinTheta1*cosPhi1 + c*(cosPhi1*u2 - sinPhi1*w1v2) + eta1*us*temp1;
                                                   >> 1305      G4double vt   = b*sinTheta1*sinPhi1 + c*(sinPhi1*u2 + cosPhi1*w1v2) + eta1*vs*temp1;
                                                   >> 1306      G4double wt   = eta1*(1+temp) +       b*cosTheta1 +  c*cosTheta2    + eta1*ws*temp1;
                                                   >> 1307 
                                                   >> 1308      // long step correction
                                                   >> 1309      ut *=par;
                                                   >> 1310      vt *=par;
                                                   >> 1311      wt *=par;
                                                   >> 1312 
                                                   >> 1313      // final position relative to the pre-step point in the scattering frame
                                                   >> 1314      // ut = x_f/s so needs to multiply by s
                                                   >> 1315      x_coord = ut*fTheTrueStepLenght;
                                                   >> 1316      y_coord = vt*fTheTrueStepLenght;
                                                   >> 1317      z_coord = wt*fTheTrueStepLenght;
                                                   >> 1318 
                                                   >> 1319      if(fIsEverythingWasDone){
                                                   >> 1320        // We sample in the step limit so set fTheZPathLenght = transportDistance
                                                   >> 1321        // and lateral displacement (x_coord,y_coord,z_coord-transportDistance)
                                                   >> 1322        //Calculate transport distance
                                                   >> 1323        G4double transportDistance  = std::sqrt(x_coord*x_coord+y_coord*y_coord+z_coord*z_coord);
                                                   >> 1324        // protection
                                                   >> 1325        if(transportDistance>fTheTrueStepLenght)
                                                   >> 1326           transportDistance = fTheTrueStepLenght;
                                                   >> 1327        fTheZPathLenght = transportDistance;
                                                   >> 1328      }
                                                   >> 1329      // else:: we sample in the DoIt so
                                                   >> 1330      //       the fTheZPathLenght was already set and was taken as transport along zet
                                                   >> 1331      fTheDisplacementVector.set(x_coord,y_coord,z_coord-fTheZPathLenght);
                                                   >> 1332   } else {
                                                   >> 1333      // compute zz = <z>/tPathLength
                                                   >> 1334      // s -> true-path-length
                                                   >> 1335      // z -> geom-path-length:: when PRESTA is used z =(def.) <z>
                                                   >> 1336      // r -> lateral displacement = s/2 sin(theta)  => x_f = r cos(phi); y_f = r sin(phi)
                                                   >> 1337      G4double zz = 0.0;
                                                   >> 1338      if(fIsEverythingWasDone){
                                                   >> 1339         // We sample in the step limit so set fTheZPathLenght = transportDistance
                                                   >> 1340         // and lateral displacement (x_coord,y_coord,z_coord-transportDistance)
                                                   >> 1341         if(Qn1<0.1) { // use 3-order Taylor approximation of (1-exp(-x))/x around x=0
                                                   >> 1342           zz = 1.0 - Qn1*(0.5 - Qn1*(0.166666667 - 0.041666667*Qn1)); // 1/6 =0.166..7 ; 1/24=0.041..
                                                   >> 1343         } else {
                                                   >> 1344           zz = (1.-G4Exp(-Qn1))/Qn1;
                                                   >> 1345         }
                                                   >> 1346      } else {
                                                   >> 1347         // we sample in the DoIt so
                                                   >> 1348         // the fTheZPathLenght was already set and was taken as transport along zet
                                                   >> 1349         zz = fTheZPathLenght/fTheTrueStepLenght;
                                                   >> 1350      }
                                                   >> 1351 
                                                   >> 1352      G4double rr = (1.-zz*zz)/(1.-ws*ws); // s^2 >= <z>^2+r^2  :: where r^2 = s^2/4 sin^2(theta)
                                                   >> 1353      if(rr >= 0.25) rr = 0.25;            // (1-<z>^2/s^2)/sin^2(theta) >= r^2/(s^2 sin^2(theta)) = 1/4 must hold
                                                   >> 1354      G4double rperp = fTheTrueStepLenght*std::sqrt(rr);  // this is r/sint
                                                   >> 1355      x_coord  = rperp*us;
                                                   >> 1356      y_coord  = rperp*vs;
                                                   >> 1357      z_coord  = zz*fTheTrueStepLenght;
                                                   >> 1358 
                                                   >> 1359      if(fIsEverythingWasDone){
                                                   >> 1360        G4double transportDistance = std::sqrt(x_coord*x_coord + y_coord*y_coord + z_coord*z_coord);
                                                   >> 1361        fTheZPathLenght = transportDistance;
                                                   >> 1362      }
                                                   >> 1363 
                                                   >> 1364      fTheDisplacementVector.set(x_coord,y_coord,z_coord- fTheZPathLenght);
                                                   >> 1365    }
                                                   >> 1366 }
                                                   >> 1367 */
1152                                                  1368