Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4LowEPPolarizedComptonModel.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/lowenergy/src/G4LowEPPolarizedComptonModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4LowEPPolarizedComptonModel.cc (Version 10.4.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 // *******************************************     26 // *********************************************************************
 27 // |                                               27 // |                                                                   |
 28 // |      G4LowEPPolarizedComptonModel-- Geant     28 // |      G4LowEPPolarizedComptonModel-- Geant4 Monash University      |
 29 // |         polarised low energy Compton scat     29 // |         polarised low energy Compton scattering model.            |
 30 // |          J. M. C. Brown, Monash Universit     30 // |          J. M. C. Brown, Monash University, Australia             |
 31 // |                                               31 // |                                                                   |
 32 // |                                               32 // |                                                                   |
 33 // *******************************************     33 // *********************************************************************
 34 // |                                               34 // |                                                                   |
 35 // | The following is a Geant4 class to simula     35 // | The following is a Geant4 class to simulate the process of        |
 36 // | bound electron Compton scattering. Genera     36 // | bound electron Compton scattering. General code structure is      |
 37 // | based on G4LowEnergyCompton.cc and            37 // | based on G4LowEnergyCompton.cc and                                |
 38 // | G4LivermorePolarizedComptonModel.cc.          38 // | G4LivermorePolarizedComptonModel.cc.                              |
 39 // | Algorithms for photon energy, and ejected     39 // | Algorithms for photon energy, and ejected Compton electron        |
 40 // | direction taken from:                         40 // | direction taken from:                                             |
 41 // |                                               41 // |                                                                   |
 42 // | J. M. C. Brown, M. R. Dimmock, J. E. Gill     42 // | J. M. C. Brown, M. R. Dimmock, J. E. Gillam and D. M. Paganin,    |
 43 // | "A low energy bound atomic electron Compt     43 // | "A low energy bound atomic electron Compton scattering model      |
 44 // |  for Geant4", NIMB, Vol. 338, 77-88, 2014     44 // |  for Geant4", NIMB, Vol. 338, 77-88, 2014.                        |
 45 // |                                               45 // |                                                                   |
 46 // | The author acknowledges the work of the G     46 // | The author acknowledges the work of the Geant4 collaboration      |
 47 // | in developing the following algorithms th     47 // | in developing the following algorithms that have been employed    |
 48 // | or adapeted for the present software:         48 // | or adapeted for the present software:                             |    
 49 // |                                               49 // |                                                                   |
 50 // |  # sampling of photon scattering angle,       50 // |  # sampling of photon scattering angle,                           |
 51 // |  # target element selection in composite      51 // |  # target element selection in composite materials,               |
 52 // |  # target shell selection in element,         52 // |  # target shell selection in element,                             |
 53 // |  # and sampling of bound electron momentu     53 // |  # and sampling of bound electron momentum from Compton profiles. |
 54 // |                                               54 // |                                                                   |
 55 // *******************************************     55 // *********************************************************************
 56 // |                                               56 // |                                                                   |
 57 // | History:                                      57 // | History:                                                          |
 58 // | --------                                      58 // | --------                                                          |
 59 // |                                               59 // |                                                                   |
 60 // | Jan. 2015 JMCB       - 1st Version based      60 // | Jan. 2015 JMCB       - 1st Version based on G4LowEPPComptonModel  |
 61 // | Feb. 2016 JMCB       - Geant4 10.2 FPE fi     61 // | Feb. 2016 JMCB       - Geant4 10.2 FPE fix for bug 1676           |
 62 // | Nov. 2016 JMCB       - Polarisation track     62 // | Nov. 2016 JMCB       - Polarisation tracking fix in collaboration |
 63 // |                        of Dr. Merlin Reyn     63 // |                        of Dr. Merlin Reynaard Kole,               |
 64 // |                        University of Gene     64 // |                        University of Geneva                       |
 65 // |                                               65 // |                                                                   |
 66 // *******************************************     66 // *********************************************************************
 67                                                    67 
 68 #include "G4LowEPPolarizedComptonModel.hh"         68 #include "G4LowEPPolarizedComptonModel.hh"
 69 #include "G4AutoLock.hh"                       << 
 70 #include "G4PhysicalConstants.hh"                  69 #include "G4PhysicalConstants.hh"
 71 #include "G4SystemOfUnits.hh"                      70 #include "G4SystemOfUnits.hh"
 72                                                    71 
 73 //********************************************     72 //****************************************************************************
 74                                                    73 
 75 using namespace std;                               74 using namespace std;
 76 namespace { G4Mutex LowEPPolarizedComptonModel << 
 77                                                << 
 78                                                    75 
 79 G4PhysicsFreeVector* G4LowEPPolarizedComptonMo <<  76 G4int G4LowEPPolarizedComptonModel::maxZ = 99;
 80 G4ShellData*       G4LowEPPolarizedComptonMode <<  77 G4LPhysicsFreeVector* G4LowEPPolarizedComptonModel::data[] = {0};
 81 G4DopplerProfile*  G4LowEPPolarizedComptonMode <<  78 G4ShellData*       G4LowEPPolarizedComptonModel::shellData = 0;
                                                   >>  79 G4DopplerProfile*  G4LowEPPolarizedComptonModel::profileData = 0;
 82                                                    80 
 83 static const G4double ln10 = G4Log(10.);           81 static const G4double ln10 = G4Log(10.);
 84                                                    82 
 85 G4LowEPPolarizedComptonModel::G4LowEPPolarized     83 G4LowEPPolarizedComptonModel::G4LowEPPolarizedComptonModel(const G4ParticleDefinition*,
 86                                                    84                                                  const G4String& nam)
 87   : G4VEmModel(nam),isInitialised(false)           85   : G4VEmModel(nam),isInitialised(false)
 88 {                                                  86 {
 89   verboseLevel=1 ;                                 87   verboseLevel=1 ;
 90   // Verbosity scale:                              88   // Verbosity scale:
 91   // 0 = nothing                                   89   // 0 = nothing 
 92   // 1 = warning for energy non-conservation       90   // 1 = warning for energy non-conservation 
 93   // 2 = details of energy budget                  91   // 2 = details of energy budget
 94   // 3 = calculation of cross sections, file o     92   // 3 = calculation of cross sections, file openings, sampling of atoms
 95   // 4 = entering in methods                       93   // 4 = entering in methods
 96                                                    94 
 97   if(  verboseLevel>1 ) {                          95   if(  verboseLevel>1 ) {
 98     G4cout << "Low energy photon Compton model     96     G4cout << "Low energy photon Compton model is constructed " << G4endl;
 99   }                                                97   }
100                                                    98 
101   //Mark this model as "applicable" for atomic     99   //Mark this model as "applicable" for atomic deexcitation
102   SetDeexcitationFlag(true);                      100   SetDeexcitationFlag(true);
103                                                   101 
104   fParticleChange = nullptr;                   << 102   fParticleChange = 0;
105   fAtomDeexcitation = nullptr;                 << 103   fAtomDeexcitation = 0;
106 }                                                 104 }
107                                                   105 
108 //********************************************    106 //****************************************************************************
109                                                   107 
110 G4LowEPPolarizedComptonModel::~G4LowEPPolarize    108 G4LowEPPolarizedComptonModel::~G4LowEPPolarizedComptonModel()
111 {                                                 109 {
112   if(IsMaster()) {                                110   if(IsMaster()) {
113     delete shellData;                             111     delete shellData;
114     shellData = nullptr;                       << 112     shellData = 0;
115     delete profileData;                           113     delete profileData;
116     profileData = nullptr;                     << 114     profileData = 0;
117   }                                               115   }
118 }                                                 116 }
119                                                   117 
120 //********************************************    118 //****************************************************************************
121                                                   119 
122 void G4LowEPPolarizedComptonModel::Initialise(    120 void G4LowEPPolarizedComptonModel::Initialise(const G4ParticleDefinition* particle,
123                                          const    121                                          const G4DataVector& cuts)
124 {                                                 122 {
125   if (verboseLevel > 1) {                         123   if (verboseLevel > 1) {
126     G4cout << "Calling G4LowEPPolarizedCompton    124     G4cout << "Calling G4LowEPPolarizedComptonModel::Initialise()" << G4endl;
127   }                                               125   }
128                                                   126 
129   // Initialise element selector                  127   // Initialise element selector
                                                   >> 128 
130   if(IsMaster()) {                                129   if(IsMaster()) {
                                                   >> 130 
131     // Access to elements                         131     // Access to elements
132     const char* path = G4FindDataDir("G4LEDATA << 132 
                                                   >> 133     char* path = getenv("G4LEDATA");
133                                                   134 
134     G4ProductionCutsTable* theCoupleTable =       135     G4ProductionCutsTable* theCoupleTable =
135       G4ProductionCutsTable::GetProductionCuts    136       G4ProductionCutsTable::GetProductionCutsTable();
136     G4int numOfCouples = (G4int)theCoupleTable << 137     G4int numOfCouples = theCoupleTable->GetTableSize();
137                                                   138 
138     for(G4int i=0; i<numOfCouples; ++i) {         139     for(G4int i=0; i<numOfCouples; ++i) {
139       const G4Material* material =                140       const G4Material* material =
140         theCoupleTable->GetMaterialCutsCouple(    141         theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
141       const G4ElementVector* theElementVector     142       const G4ElementVector* theElementVector = material->GetElementVector();
142       std::size_t nelm = material->GetNumberOf << 143       G4int nelm = material->GetNumberOfElements();
143                                                   144 
144       for (std::size_t j=0; j<nelm; ++j) {     << 145       for (G4int j=0; j<nelm; ++j) {
145         G4int Z = G4lrint((*theElementVector)[    146         G4int Z = G4lrint((*theElementVector)[j]->GetZ());
146         if(Z < 1)        { Z = 1; }               147         if(Z < 1)        { Z = 1; }
147         else if(Z > maxZ){ Z = maxZ; }            148         else if(Z > maxZ){ Z = maxZ; }
148                                                   149 
149         if( (!data[Z]) ) { ReadData(Z, path);     150         if( (!data[Z]) ) { ReadData(Z, path); }
150       }                                           151       }
151     }                                             152     }
152                                                   153 
153     // For Doppler broadening                     154     // For Doppler broadening
154     if(!shellData) {                              155     if(!shellData) {
155       shellData = new G4ShellData();              156       shellData = new G4ShellData();
156       shellData->SetOccupancyData();              157       shellData->SetOccupancyData();
157       G4String file = "/doppler/shell-doppler"    158       G4String file = "/doppler/shell-doppler";
158       shellData->LoadData(file);                  159       shellData->LoadData(file);
159     }                                             160     }
160     if(!profileData) { profileData = new G4Dop    161     if(!profileData) { profileData = new G4DopplerProfile(); }
161                                                   162 
162     InitialiseElementSelectors(particle, cuts)    163     InitialiseElementSelectors(particle, cuts);
163   }                                               164   }
164                                                   165 
165   if (verboseLevel > 2) {                         166   if (verboseLevel > 2) {
166     G4cout << "Loaded cross section files" <<     167     G4cout << "Loaded cross section files" << G4endl;
167   }                                               168   }
168                                                   169 
169   if( verboseLevel>1 ) {                          170   if( verboseLevel>1 ) {
170     G4cout << "G4LowEPPolarizedComptonModel is    171     G4cout << "G4LowEPPolarizedComptonModel is initialized " << G4endl
171            << "Energy range: "                    172            << "Energy range: "
172            << LowEnergyLimit() / eV << " eV -     173            << LowEnergyLimit() / eV << " eV - "
173            << HighEnergyLimit() / GeV << " GeV    174            << HighEnergyLimit() / GeV << " GeV"
174            << G4endl;                             175            << G4endl;
175   }                                               176   }
176                                                   177 
177   if(isInitialised) { return; }                   178   if(isInitialised) { return; }
178                                                   179   
179   fParticleChange = GetParticleChangeForGamma(    180   fParticleChange = GetParticleChangeForGamma();
180   fAtomDeexcitation  = G4LossTableManager::Ins    181   fAtomDeexcitation  = G4LossTableManager::Instance()->AtomDeexcitation();
181   isInitialised = true;                           182   isInitialised = true;
182 }                                                 183 }
183                                                   184 
184 //********************************************    185 //****************************************************************************
185                                                   186 
186 void G4LowEPPolarizedComptonModel::InitialiseL    187 void G4LowEPPolarizedComptonModel::InitialiseLocal(const G4ParticleDefinition*,
187                                                   188                                               G4VEmModel* masterModel)
188 {                                                 189 {
189   SetElementSelectors(masterModel->GetElementS    190   SetElementSelectors(masterModel->GetElementSelectors());
190 }                                                 191 }
191                                                   192 
192 //********************************************    193 //****************************************************************************
193                                                   194 
194 void G4LowEPPolarizedComptonModel::ReadData(st << 195 void G4LowEPPolarizedComptonModel::ReadData(size_t Z, const char* path)
195 {                                                 196 {
196   if (verboseLevel > 1)                           197   if (verboseLevel > 1)
197   {                                               198   {
198     G4cout << "G4LowEPPolarizedComptonModel::R    199     G4cout << "G4LowEPPolarizedComptonModel::ReadData()"
199            << G4endl;                             200            << G4endl;
200   }                                               201   }
201   if(data[Z]) { return; }                         202   if(data[Z]) { return; }
202   const char* datadir = path;                     203   const char* datadir = path;
203   if(!datadir)                                    204   if(!datadir)
204   {                                               205   {
205     datadir = G4FindDataDir("G4LEDATA");       << 206     datadir = getenv("G4LEDATA");
206     if(!datadir)                                  207     if(!datadir)
207     {                                             208     {
208       G4Exception("G4LowEPPolarizedComptonMode    209       G4Exception("G4LowEPPolarizedComptonModel::ReadData()",
209                   "em0006",FatalException,        210                   "em0006",FatalException,
210                   "Environment variable G4LEDA    211                   "Environment variable G4LEDATA not defined");
211       return;                                     212       return;
212     }                                             213     }
213   }                                               214   }
214                                                   215 
215   data[Z] = new G4PhysicsFreeVector();         << 216   data[Z] = new G4LPhysicsFreeVector();
                                                   >> 217 
                                                   >> 218   // Activation of spline interpolation
                                                   >> 219   data[Z]->SetSpline(false);
216                                                   220 
217   std::ostringstream ost;                         221   std::ostringstream ost;
218   ost << datadir << "/livermore/comp/ce-cs-" <    222   ost << datadir << "/livermore/comp/ce-cs-" << Z <<".dat";
219   std::ifstream fin(ost.str().c_str());           223   std::ifstream fin(ost.str().c_str());
220                                                   224 
221   if( !fin.is_open())                             225   if( !fin.is_open())
222     {                                             226     {
223       G4ExceptionDescription ed;                  227       G4ExceptionDescription ed;
224       ed << "G4LowEPPolarizedComptonModel data    228       ed << "G4LowEPPolarizedComptonModel data file <" << ost.str().c_str()
225          << "> is not opened!" << G4endl;         229          << "> is not opened!" << G4endl;
226     G4Exception("G4LowEPPolarizedComptonModel:    230     G4Exception("G4LowEPPolarizedComptonModel::ReadData()",
227                 "em0003",FatalException,          231                 "em0003",FatalException,
228                 ed,"G4LEDATA version should be    232                 ed,"G4LEDATA version should be G4EMLOW6.34 or later");
229       return;                                     233       return;
230     } else {                                      234     } else {
231       if(verboseLevel > 3) {                      235       if(verboseLevel > 3) {
232         G4cout << "File " << ost.str()            236         G4cout << "File " << ost.str()
233                << " is opened by G4LowEPPolari    237                << " is opened by G4LowEPPolarizedComptonModel" << G4endl;
234       }                                           238       }
235       data[Z]->Retrieve(fin, true);               239       data[Z]->Retrieve(fin, true);
236       data[Z]->ScaleVector(MeV, MeV*barn);        240       data[Z]->ScaleVector(MeV, MeV*barn);
237     }                                             241     }
238   fin.close();                                    242   fin.close();
239 }                                                 243 }
240                                                   244 
241 //********************************************    245 //****************************************************************************
242                                                   246 
                                                   >> 247 
243 G4double                                          248 G4double 
244 G4LowEPPolarizedComptonModel::ComputeCrossSect    249 G4LowEPPolarizedComptonModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
245                                                   250                                                     G4double GammaEnergy,
246                                                   251                                                     G4double Z, G4double,
247                                                   252                                                     G4double, G4double)
248 {                                                 253 {
249   if (verboseLevel > 3) {                         254   if (verboseLevel > 3) {
250     G4cout << "G4LowEPPolarizedComptonModel::C    255     G4cout << "G4LowEPPolarizedComptonModel::ComputeCrossSectionPerAtom()"
251            << G4endl;                             256            << G4endl;
252   }                                               257   }
253   G4double cs = 0.0;                              258   G4double cs = 0.0;
254                                                   259 
255   if (GammaEnergy < LowEnergyLimit()) { return    260   if (GammaEnergy < LowEnergyLimit()) { return 0.0; }
256                                                   261 
257   G4int intZ = G4lrint(Z);                        262   G4int intZ = G4lrint(Z);
258   if(intZ < 1 || intZ > maxZ) { return cs; }      263   if(intZ < 1 || intZ > maxZ) { return cs; }
259                                                   264 
260   G4PhysicsFreeVector* pv = data[intZ];        << 265   G4LPhysicsFreeVector* pv = data[intZ];
261                                                   266 
262   // if element was not initialised               267   // if element was not initialised
263   // do initialisation safely for MT mode         268   // do initialisation safely for MT mode
264   if(!pv)                                         269   if(!pv)
265     {                                             270     {
266       InitialiseForElement(0, intZ);              271       InitialiseForElement(0, intZ);
267       pv = data[intZ];                            272       pv = data[intZ];
268       if(!pv) { return cs; }                      273       if(!pv) { return cs; }
269     }                                             274     }
270                                                   275 
271   G4int n = G4int(pv->GetVectorLength() - 1);  << 276   G4int n = pv->GetVectorLength() - 1;
272   G4double e1 = pv->Energy(0);                    277   G4double e1 = pv->Energy(0);
273   G4double e2 = pv->Energy(n);                    278   G4double e2 = pv->Energy(n);
274                                                   279 
275   if(GammaEnergy <= e1)      { cs = GammaEnerg    280   if(GammaEnergy <= e1)      { cs = GammaEnergy/(e1*e1)*pv->Value(e1); }
276   else if(GammaEnergy <= e2) { cs = pv->Value(    281   else if(GammaEnergy <= e2) { cs = pv->Value(GammaEnergy)/GammaEnergy; }
277   else if(GammaEnergy > e2)  { cs = pv->Value(    282   else if(GammaEnergy > e2)  { cs = pv->Value(e2)/GammaEnergy; }
278                                                   283 
279   return cs;                                      284   return cs;
280 }                                                 285 }
281                                                   286 
282 //********************************************    287 //****************************************************************************
283                                                   288 
284 void G4LowEPPolarizedComptonModel::SampleSecon    289 void G4LowEPPolarizedComptonModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
285                  const G4MaterialCutsCouple* c << 290                                                 const G4MaterialCutsCouple* couple,
286                  const G4DynamicParticle* aDyn << 291                                                 const G4DynamicParticle* aDynamicGamma,
287                  G4double, G4double)           << 292                                                 G4double, G4double)
288 {                                                 293 {
289                                                   294 
290   //Determine number of digits (in decimal bas << 295     //Determine number of digits (in decimal base) that G4double can accurately represent
291   G4double g4d_order = G4double(numeric_limits << 296      G4double g4d_order = G4double(numeric_limits<G4double>::digits10);
292   G4double g4d_limit = std::pow(10.,-g4d_order << 297      G4double g4d_limit = std::pow(10.,-g4d_order);
293                                                   298 
294   // The scattered gamma energy is sampled acc    299   // The scattered gamma energy is sampled according to Klein - Nishina formula.
295   // then accepted or rejected depending on th    300   // then accepted or rejected depending on the Scattering Function multiplied
296   // by factor from Klein - Nishina formula.      301   // by factor from Klein - Nishina formula.
297   // Expression of the angular distribution as    302   // Expression of the angular distribution as Klein Nishina
298   // angular and energy distribution and Scatt    303   // angular and energy distribution and Scattering fuctions is taken from
299   // D. E. Cullen "A simple model of photon tr    304   // D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
300   // Phys. Res. B 101 (1995). Method of sampli    305   // Phys. Res. B 101 (1995). Method of sampling with form factors is different
301   // data are interpolated while in the articl    306   // data are interpolated while in the article they are fitted.
302   // Reference to the article is from J. Stepa    307   // Reference to the article is from J. Stepanek New Photon, Positron
303   // and Electron Interaction Data for GEANT i    308   // and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
304   // TeV (draft).                                 309   // TeV (draft).
305   // The random number techniques of Butcher &    310   // The random number techniques of Butcher & Messel are used
306   // (Nucl Phys 20(1960),15).                     311   // (Nucl Phys 20(1960),15).
307                                                   312 
                                                   >> 313 
308   G4double photonEnergy0 = aDynamicGamma->GetK    314   G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy()/MeV;
309                                                   315 
310   if (verboseLevel > 3) {                         316   if (verboseLevel > 3) {
311     G4cout << "G4LowEPPolarizedComptonModel::S    317     G4cout << "G4LowEPPolarizedComptonModel::SampleSecondaries() E(MeV)= "
312            << photonEnergy0/MeV << " in " << c    318            << photonEnergy0/MeV << " in " << couple->GetMaterial()->GetName()
313            << G4endl;                             319            << G4endl;
314   }                                               320   }
315   // do nothing below the threshold               321   // do nothing below the threshold
316   // should never get here because the XS is z    322   // should never get here because the XS is zero below the limit
317   if (photonEnergy0 < LowEnergyLimit())           323   if (photonEnergy0 < LowEnergyLimit())
318     return ;                                      324     return ;
319                                                   325 
320   G4double e0m = photonEnergy0 / electron_mass    326   G4double e0m = photonEnergy0 / electron_mass_c2 ;
321   G4ParticleMomentum photonDirection0 = aDynam    327   G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
                                                   >> 328 
322                                                   329   
323   // Polarisation: check orientation of photon    330   // Polarisation: check orientation of photon propagation direction and polarisation
324   // Fix if needed                                331   // Fix if needed
325                                                   332 
326   G4ThreeVector photonPolarization0 = aDynamic    333   G4ThreeVector photonPolarization0 = aDynamicGamma->GetPolarization();
                                                   >> 334 
327   // Check if polarisation vector is perpendic    335   // Check if polarisation vector is perpendicular and fix if not
328                                                   336 
329   if (!(photonPolarization0.isOrthogonal(photo    337   if (!(photonPolarization0.isOrthogonal(photonDirection0, 1e-6))||(photonPolarization0.mag()==0))
330     {                                             338     {
331       photonPolarization0 = GetRandomPolarizat    339       photonPolarization0 = GetRandomPolarization(photonDirection0);
332     }                                             340     }
                                                   >> 341 
333   else                                            342   else
334     {                                             343     {
335       if ((photonPolarization0.howOrthogonal(p    344       if ((photonPolarization0.howOrthogonal(photonDirection0) !=0) && (photonPolarization0.howOrthogonal(photonDirection0) > g4d_limit))
336         {                                         345         {
337           photonPolarization0 = GetPerpendicul    346           photonPolarization0 = GetPerpendicularPolarization(photonDirection0,photonPolarization0);
338         }                                         347         }
339     }                                          << 348      }
340                                                   349 
341   // Select randomly one element in the curren    350   // Select randomly one element in the current material
                                                   >> 351 
342   const G4ParticleDefinition* particle =  aDyn    352   const G4ParticleDefinition* particle =  aDynamicGamma->GetDefinition();
343   const G4Element* elm = SelectRandomAtom(coup    353   const G4Element* elm = SelectRandomAtom(couple,particle,photonEnergy0);
344   G4int Z = (G4int)elm->GetZ();                   354   G4int Z = (G4int)elm->GetZ();
345                                                   355 
346   G4double LowEPPCepsilon0 = 1. / (1. + 2. * e    356   G4double LowEPPCepsilon0 = 1. / (1. + 2. * e0m);
347   G4double LowEPPCepsilon0Sq = LowEPPCepsilon0    357   G4double LowEPPCepsilon0Sq = LowEPPCepsilon0 * LowEPPCepsilon0;
348   G4double alpha1 = -std::log(LowEPPCepsilon0)    358   G4double alpha1 = -std::log(LowEPPCepsilon0);
349   G4double alpha2 = 0.5 * (1. - LowEPPCepsilon    359   G4double alpha2 = 0.5 * (1. - LowEPPCepsilon0Sq);
350                                                   360 
351   G4double wlPhoton = h_Planck*c_light/photonE    361   G4double wlPhoton = h_Planck*c_light/photonEnergy0;
352                                                   362 
353   // Sample the energy of the scattered photon    363   // Sample the energy of the scattered photon
354   G4double LowEPPCepsilon;                        364   G4double LowEPPCepsilon;
355   G4double LowEPPCepsilonSq;                      365   G4double LowEPPCepsilonSq;
356   G4double oneCosT;                               366   G4double oneCosT;
357   G4double sinT2;                                 367   G4double sinT2;
358   G4double gReject;                               368   G4double gReject;
359                                                   369 
360   if (verboseLevel > 3) {                         370   if (verboseLevel > 3) {
361     G4cout << "Started loop to sample gamma en    371     G4cout << "Started loop to sample gamma energy" << G4endl;
362   }                                               372   }
363                                                   373 
364   do                                              374   do
365     {                                             375     {
366       if ( alpha1/(alpha1+alpha2) > G4UniformR    376       if ( alpha1/(alpha1+alpha2) > G4UniformRand())
367         {                                         377         {
368           LowEPPCepsilon = G4Exp(-alpha1 * G4U    378           LowEPPCepsilon = G4Exp(-alpha1 * G4UniformRand());
369           LowEPPCepsilonSq = LowEPPCepsilon *     379           LowEPPCepsilonSq = LowEPPCepsilon * LowEPPCepsilon;
370         }                                         380         }
371       else                                        381       else
372         {                                         382         {
373           LowEPPCepsilonSq = LowEPPCepsilon0Sq    383           LowEPPCepsilonSq = LowEPPCepsilon0Sq + (1. - LowEPPCepsilon0Sq) * G4UniformRand();
374           LowEPPCepsilon = std::sqrt(LowEPPCep    384           LowEPPCepsilon = std::sqrt(LowEPPCepsilonSq);
375         }                                         385         }
376                                                   386 
377       oneCosT = (1. - LowEPPCepsilon) / ( LowE    387       oneCosT = (1. - LowEPPCepsilon) / ( LowEPPCepsilon * e0m);
378       sinT2 = oneCosT * (2. - oneCosT);           388       sinT2 = oneCosT * (2. - oneCosT);
379       G4double x = std::sqrt(oneCosT/2.) / (wl    389       G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/cm);
380       G4double scatteringFunction = ComputeSca    390       G4double scatteringFunction = ComputeScatteringFunction(x, Z);
381       gReject = (1. - LowEPPCepsilon * sinT2 /    391       gReject = (1. - LowEPPCepsilon * sinT2 / (1. + LowEPPCepsilonSq)) * scatteringFunction;
382                                                   392 
383     } while(gReject < G4UniformRand()*Z);         393     } while(gReject < G4UniformRand()*Z);
384                                                   394 
385   G4double cosTheta = 1. - oneCosT;               395   G4double cosTheta = 1. - oneCosT;
386   G4double sinTheta = std::sqrt(sinT2);           396   G4double sinTheta = std::sqrt(sinT2);
387   G4double phi = SetPhi(LowEPPCepsilon,sinT2);    397   G4double phi = SetPhi(LowEPPCepsilon,sinT2);
388   G4double dirx = sinTheta * std::cos(phi);       398   G4double dirx = sinTheta * std::cos(phi);
389   G4double diry = sinTheta * std::sin(phi);       399   G4double diry = sinTheta * std::sin(phi);
390   G4double dirz = cosTheta ;                      400   G4double dirz = cosTheta ;
391                                                   401 
392   // Set outgoing photon polarization             402   // Set outgoing photon polarization
393                                                   403 
394   G4ThreeVector photonPolarization1 = SetNewPo    404   G4ThreeVector photonPolarization1 = SetNewPolarization(LowEPPCepsilon,
395                sinT2,                          << 405                                                         sinT2,
396                phi,                            << 406                                                         phi,
397                cosTheta);                      << 407                                                         cosTheta);
398                                                   408 
399   // Scatter photon energy and Compton electro    409   // Scatter photon energy and Compton electron direction - Method based on:
400   // J. M. C. Brown, M. R. Dimmock, J. E. Gill    410   // J. M. C. Brown, M. R. Dimmock, J. E. Gillam and D. M. Paganin'
401   // "A low energy bound atomic electron Compt    411   // "A low energy bound atomic electron Compton scattering model for Geant4"
402   // NIMB, Vol. 338, 77-88, 2014.                 412   // NIMB, Vol. 338, 77-88, 2014.
403                                                   413 
404   // Set constants and initialize scattering p    414   // Set constants and initialize scattering parameters
                                                   >> 415 
405   const G4double vel_c = c_light / (m/s);         416   const G4double vel_c = c_light / (m/s);
406   const G4double momentum_au_to_nat = halfpi*     417   const G4double momentum_au_to_nat = halfpi* hbar_Planck / Bohr_radius / (kg*m/s);
407   const G4double e_mass_kg =  electron_mass_c2    418   const G4double e_mass_kg =  electron_mass_c2 / c_squared / kg ;
408                                                   419 
409   const G4int maxDopplerIterations = 1000;        420   const G4int maxDopplerIterations = 1000;
410   G4double bindingE = 0.;                         421   G4double bindingE = 0.;
411   G4double pEIncident = photonEnergy0 ;           422   G4double pEIncident = photonEnergy0 ;
412   G4double pERecoil =  -1.;                       423   G4double pERecoil =  -1.;
413   G4double eERecoil = -1.;                        424   G4double eERecoil = -1.;
414   G4double e_alpha =0.;                           425   G4double e_alpha =0.;
415   G4double e_beta = 0.;                           426   G4double e_beta = 0.;
416                                                   427 
417   G4double CE_emission_flag = 0.;                 428   G4double CE_emission_flag = 0.;
418   G4double ePAU = -1;                             429   G4double ePAU = -1;
419   G4int shellIdx = 0;                             430   G4int shellIdx = 0;
420   G4double u_temp = 0;                            431   G4double u_temp = 0;
421   G4double cosPhiE =0;                            432   G4double cosPhiE =0;
422   G4double sinThetaE =0;                          433   G4double sinThetaE =0;
423   G4double cosThetaE =0;                          434   G4double cosThetaE =0;
424   G4int iteration = 0;                            435   G4int iteration = 0;
425                                                   436 
426   if (verboseLevel > 3) {                         437   if (verboseLevel > 3) {
427     G4cout << "Started loop to sample photon e    438     G4cout << "Started loop to sample photon energy and electron direction" << G4endl;
428   }                                               439   }
429                                                   440 
430   do{                                             441   do{
431     // *************************************** << 
432     // |     Determine scatter photon energy   << 
433     // *************************************** << 
434     do                                         << 
435       {                                        << 
436   iteration++;                                 << 
437                                                   442 
438   // ***************************************** << 
439   // |     Sample bound electron information   << 
440   // ***************************************** << 
441                                                << 
442   // Select shell based on shell occupancy     << 
443   shellIdx = shellData->SelectRandomShell(Z);  << 
444   bindingE = shellData->BindingEnergy(Z,shellI << 
445                                                << 
446   // Randomly sample bound electron momentum ( << 
447   ePAU = profileData->RandomSelectMomentum(Z,s << 
448                                                << 
449   // Convert to SI units                       << 
450   G4double ePSI = ePAU * momentum_au_to_nat;   << 
451                                                << 
452   //Calculate bound electron velocity and norm << 
453   u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / << 
454                                                << 
455   // Sample incident electron direction, amorp << 
456   e_alpha = pi*G4UniformRand();                << 
457   e_beta = twopi*G4UniformRand();              << 
458                                                << 
459   // Total energy of system                    << 
460   G4double eEIncident = electron_mass_c2 / sqr << 
461   G4double systemE = eEIncident + pEIncident;  << 
462                                                << 
463   G4double gamma_temp = 1.0 / sqrt( 1 - (u_tem << 
464   G4double numerator = gamma_temp*electron_mas << 
465   G4double subdenom1 =  u_temp*cosTheta*std::c << 
466   G4double subdenom2 = u_temp*sinTheta*std::si << 
467   G4double denominator = (1.0 - cosTheta) +  ( << 
468   pERecoil = (numerator/denominator);          << 
469   eERecoil = systemE - pERecoil;               << 
470   CE_emission_flag = pEIncident - pERecoil;    << 
471       } while ( (iteration <= maxDopplerIterat << 
472                                                << 
473     // End of recalculation of photon energy w << 
474     // *************************************** << 
475     // |     Determine ejected Compton electro << 
476     // *************************************** << 
477                                                << 
478     // Calculate velocity of ejected Compton e << 
479                                                << 
480     G4double a_temp = eERecoil / electron_mass << 
481     G4double u_p_temp = sqrt(1 - (1 / (a_temp* << 
482                                                << 
483     // Coefficients and terms from simulatenou << 
484     G4double sinAlpha = std::sin(e_alpha);     << 
485     G4double cosAlpha = std::cos(e_alpha);     << 
486     G4double sinBeta = std::sin(e_beta);       << 
487     G4double cosBeta = std::cos(e_beta);       << 
488                                                << 
489     G4double gamma = 1.0 / sqrt(1 - (u_temp*u_ << 
490     G4double gamma_p = 1.0 / sqrt(1 - (u_p_tem << 
491                                                << 
492     G4double var_A = pERecoil*u_p_temp*sinThet << 
493     G4double var_B = u_p_temp* (pERecoil*cosTh << 
494     G4double var_C = (pERecoil-pEIncident) - ( << 
495                                                << 
496     G4double var_D1 = gamma*electron_mass_c2*p << 
497     G4double var_D2 = (1 - (u_temp*cosTheta*co << 
498     G4double var_D3 = ((electron_mass_c2*elect << 
499     G4double var_D = var_D1*var_D2 + var_D3;   << 
500                                                << 
501     G4double var_E1 = ((gamma*gamma_p)*(electr << 
502     G4double var_E2 = gamma_p*electron_mass_c2 << 
503     G4double var_E = var_E1 - var_E2;          << 
504                                                << 
505     G4double var_F1 = ((gamma*gamma_p)*(electr << 
506     G4double var_F2 = (gamma_p*electron_mass_c << 
507     G4double var_F = var_F1 - var_F2;          << 
508                                                << 
509     G4double var_G = (gamma*gamma_p)*(electron << 
510                                                << 
511     // Two equations form a quadratic form of  << 
512     // Coefficents and solution to quadratic   << 
513     G4double var_W1 = (var_F*var_B - var_E*var << 
514     G4double var_W2 = (var_G*var_G)*(var_A*var << 
515     G4double var_W = var_W1 + var_W2;          << 
516                                                << 
517     G4double var_Y = 2.0*(((var_A*var_D-var_F* << 
518                                                << 
519     G4double var_Z1 = (var_A*var_D - var_F*var << 
520     G4double var_Z2 = (var_G*var_G)*(var_C*var << 
521     G4double var_Z = var_Z1 + var_Z2;          << 
522     G4double diff1 = var_Y*var_Y;              << 
523     G4double diff2 = 4*var_W*var_Z;            << 
524     G4double diff = diff1 - diff2;             << 
525                                                << 
526     // Check if diff is less than zero, if so  << 
527     //Confirm that diff less than zero is due  << 
528     //than 10^(-g4d_order), then set diff to z << 
529                                                   443 
530     if ((diff < 0.0) && (abs(diff / diff1) < g << 444       // ******************************************
531       {                                        << 445       // |     Determine scatter photon energy    |
532   diff = 0.0;                                  << 446       // ******************************************   
533       }                                        << 447 
                                                   >> 448  do
                                                   >> 449     {
                                                   >> 450       iteration++;
                                                   >> 451 
                                                   >> 452 
                                                   >> 453       // ********************************************
                                                   >> 454       // |     Sample bound electron information    |
                                                   >> 455       // ********************************************
                                                   >> 456 
                                                   >> 457       // Select shell based on shell occupancy
                                                   >> 458 
                                                   >> 459       shellIdx = shellData->SelectRandomShell(Z);
                                                   >> 460       bindingE = shellData->BindingEnergy(Z,shellIdx)/MeV;
                                                   >> 461 
                                                   >> 462 
                                                   >> 463       // Randomly sample bound electron momentum (memento: the data set is in Atomic Units)
                                                   >> 464       ePAU = profileData->RandomSelectMomentum(Z,shellIdx);
                                                   >> 465 
                                                   >> 466       // Convert to SI units     
                                                   >> 467       G4double ePSI = ePAU * momentum_au_to_nat;
                                                   >> 468 
                                                   >> 469       //Calculate bound electron velocity and normalise to natural units
                                                   >> 470       u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)) )/vel_c;
                                                   >> 471 
                                                   >> 472       // Sample incident electron direction, amorphous material, to scattering photon scattering plane 
                                                   >> 473 
                                                   >> 474       e_alpha = pi*G4UniformRand();
                                                   >> 475       e_beta = twopi*G4UniformRand();
                                                   >> 476 
                                                   >> 477       // Total energy of system  
                                                   >> 478 
                                                   >> 479       G4double eEIncident = electron_mass_c2 / sqrt( 1 - (u_temp*u_temp));
                                                   >> 480       G4double systemE = eEIncident + pEIncident;
                                                   >> 481 
                                                   >> 482 
                                                   >> 483       G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
                                                   >> 484       G4double numerator = gamma_temp*electron_mass_c2*(1 - u_temp * std::cos(e_alpha));
                                                   >> 485       G4double subdenom1 =  u_temp*cosTheta*std::cos(e_alpha);
                                                   >> 486       G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
                                                   >> 487       G4double denominator = (1.0 - cosTheta) +  (gamma_temp*electron_mass_c2*(1 - subdenom1 - subdenom2) / pEIncident);
                                                   >> 488       pERecoil = (numerator/denominator);
                                                   >> 489       eERecoil = systemE - pERecoil;
                                                   >> 490       CE_emission_flag = pEIncident - pERecoil;
                                                   >> 491     } while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
                                                   >> 492 
                                                   >> 493 // End of recalculation of photon energy with Doppler broadening
                                                   >> 494 
                                                   >> 495 
                                                   >> 496 
                                                   >> 497    // *******************************************************
                                                   >> 498    // |     Determine ejected Compton electron direction    |
                                                   >> 499    // *******************************************************      
                                                   >> 500 
                                                   >> 501       // Calculate velocity of ejected Compton electron   
                                                   >> 502 
                                                   >> 503       G4double a_temp = eERecoil / electron_mass_c2;
                                                   >> 504       G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
                                                   >> 505 
                                                   >> 506       // Coefficients and terms from simulatenous equations     
                                                   >> 507 
                                                   >> 508       G4double sinAlpha = std::sin(e_alpha);
                                                   >> 509       G4double cosAlpha = std::cos(e_alpha);
                                                   >> 510       G4double sinBeta = std::sin(e_beta);
                                                   >> 511       G4double cosBeta = std::cos(e_beta);
                                                   >> 512 
                                                   >> 513       G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
                                                   >> 514       G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
534                                                   515 
535     // Plus and minus of quadratic             << 516       G4double var_A = pERecoil*u_p_temp*sinTheta;
536     G4double X_p = (-var_Y + sqrt (diff))/(2*v << 517       G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
537     G4double X_m = (-var_Y - sqrt (diff))/(2*v << 518       G4double var_C = (pERecoil-pEIncident) - ( (pERecoil*pEIncident) / (gamma_p*electron_mass_c2))*(1 - cosTheta);
538                                                << 
539     // Floating point precision protection     << 
540     // Check if X_p and X_m are greater than o << 
541     // Issue due to propagation of FPE and onl << 
542     if(X_p >1){X_p=1;} if(X_p<-1){X_p=-1;}     << 
543     if(X_m >1){X_m=1;} if(X_m<-1){X_m=-1;}     << 
544     // End of FP protection                    << 
545                                                   519 
546     G4double ThetaE = 0.;                      << 520       G4double var_D1 = gamma*electron_mass_c2*pERecoil;
                                                   >> 521       G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
                                                   >> 522       G4double var_D3 = ((electron_mass_c2*electron_mass_c2)*(gamma*gamma_p - 1)) - (gamma_p*electron_mass_c2*pERecoil);
                                                   >> 523       G4double var_D = var_D1*var_D2 + var_D3;
547                                                   524 
548     // Randomly sample one of the two possible << 525       G4double var_E1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosAlpha);
549     G4double sol_select = G4UniformRand();     << 526       G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
                                                   >> 527       G4double var_E = var_E1 - var_E2;
550                                                   528 
551     if (sol_select < 0.5)                      << 529       G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
                                                   >> 530       G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
                                                   >> 531       G4double var_F = var_F1 - var_F2;
                                                   >> 532 
                                                   >> 533       G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
                                                   >> 534 
                                                   >> 535       // Two equations form a quadratic form of Wx^2 + Yx + Z = 0
                                                   >> 536       // Coefficents and solution to quadratic
                                                   >> 537 
                                                   >> 538       G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
                                                   >> 539       G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
                                                   >> 540       G4double var_W = var_W1 + var_W2;
                                                   >> 541 
                                                   >> 542       G4double var_Y = 2.0*(((var_A*var_D-var_F*var_C)*(var_F*var_B-var_E*var_A)) - ((var_G*var_G)*var_B*var_C));
                                                   >> 543 
                                                   >> 544       G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
                                                   >> 545       G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
                                                   >> 546       G4double var_Z = var_Z1 + var_Z2;
                                                   >> 547       G4double diff1 = var_Y*var_Y;
                                                   >> 548       G4double diff2 = 4*var_W*var_Z;
                                                   >> 549       G4double diff = diff1 - diff2;
                                                   >> 550 
                                                   >> 551 
                                                   >> 552      // Check if diff is less than zero, if so ensure it is due to FPE
                                                   >> 553 
                                                   >> 554      //Confirm that diff less than zero is due FPE, i.e if abs of diff / diff1 and diff/ diff2 is less 
                                                   >> 555      //than 10^(-g4d_order), then set diff to zero
                                                   >> 556 
                                                   >> 557      if ((diff < 0.0) && (abs(diff / diff1) < g4d_limit) && (abs(diff / diff2) < g4d_limit) )
                                                   >> 558      {
                                                   >> 559            diff = 0.0;
                                                   >> 560      }
                                                   >> 561 
                                                   >> 562       // Plus and minus of quadratic
                                                   >> 563       G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
                                                   >> 564       G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
                                                   >> 565 
                                                   >> 566 
                                                   >> 567       // Floating point precision protection
                                                   >> 568       // Check if X_p and X_m are greater than or less than 1 or -1, if so clean up FPE 
                                                   >> 569       // Issue due to propagation of FPE and only impacts 8th sig fig onwards
                                                   >> 570 
                                                   >> 571       if(X_p >1){X_p=1;} if(X_p<-1){X_p=-1;}
                                                   >> 572       if(X_m >1){X_m=1;} if(X_m<-1){X_m=-1;}
                                                   >> 573 
                                                   >> 574       // End of FP protection
                                                   >> 575 
                                                   >> 576       G4double ThetaE = 0.;
                                                   >> 577 
                                                   >> 578 
                                                   >> 579       // Randomly sample one of the two possible solutions and determin theta angle of ejected Compton electron
                                                   >> 580        G4double sol_select = G4UniformRand();
                                                   >> 581 
                                                   >> 582       if (sol_select < 0.5)
552       {                                           583       {
553   ThetaE = std::acos(X_p);                     << 584            ThetaE = std::acos(X_p);
554       }                                           585       }
555     if (sol_select > 0.5)                      << 586       if (sol_select > 0.5)
556       {                                           587       {
557   ThetaE = std::acos(X_m);                     << 588           ThetaE = std::acos(X_m);
558       }                                           589       }
559                                                   590 
560     cosThetaE = std::cos(ThetaE);              << 591       cosThetaE = std::cos(ThetaE);
561     sinThetaE = std::sin(ThetaE);              << 592       sinThetaE = std::sin(ThetaE);
562     G4double Theta = std::acos(cosTheta);      << 593       G4double Theta = std::acos(cosTheta);
563                                                << 594 
564     //Calculate electron Phi                   << 595       //Calculate electron Phi
565     G4double iSinThetaE = std::sqrt(1+std::tan << 596       G4double iSinThetaE = std::sqrt(1+std::tan((pi/2.0)-ThetaE)*std::tan((pi/2.0)-ThetaE));
566     G4double iSinTheta = std::sqrt(1+std::tan( << 597       G4double iSinTheta = std::sqrt(1+std::tan((pi/2.0)-Theta)*std::tan((pi/2.0)-Theta));
567     G4double ivar_A = iSinTheta/ (pERecoil*u_p << 598       G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
568     // Trigs                                   << 599       // Trigs
569     cosPhiE = (var_C - var_B*cosThetaE)*(ivar_ << 600       cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
570     // End of calculation of ejection Compton  << 601 
571     //Fix for floating point errors            << 602      // End of calculation of ejection Compton electron direction
572   } while ( (iteration <= maxDopplerIterations << 603 
                                                   >> 604       //Fix for floating point errors
                                                   >> 605 
                                                   >> 606     } while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
573                                                   607 
574   // Revert to original if maximum number of i << 608    // Revert to original if maximum number of iterations threshold has been reached     
575   if (iteration >= maxDopplerIterations)          609   if (iteration >= maxDopplerIterations)
576     {                                             610     {
577       pERecoil = photonEnergy0 ;                  611       pERecoil = photonEnergy0 ;
578       bindingE = 0.;                              612       bindingE = 0.;
579       dirx=0.0;                                   613       dirx=0.0;
580       diry=0.0;                                   614       diry=0.0;
581       dirz=1.0;                                   615       dirz=1.0;
582     }                                             616     }
583                                                   617 
584   // Set "scattered" photon direction and ener    618   // Set "scattered" photon direction and energy
                                                   >> 619 
585   G4ThreeVector photonDirection1(dirx,diry,dir    620   G4ThreeVector photonDirection1(dirx,diry,dirz);
586   SystemOfRefChange(photonDirection0,photonDir    621   SystemOfRefChange(photonDirection0,photonDirection1,
587         photonPolarization0,photonPolarization    622         photonPolarization0,photonPolarization1);
588                                                   623 
                                                   >> 624 
589   if (pERecoil > 0.)                              625   if (pERecoil > 0.)
590     {                                             626     {
591       fParticleChange->SetProposedKineticEnerg << 627      fParticleChange->SetProposedKineticEnergy(pERecoil) ;
592       fParticleChange->ProposeMomentumDirectio << 628      fParticleChange->ProposeMomentumDirection(photonDirection1) ;
593       fParticleChange->ProposePolarization(pho << 629      fParticleChange->ProposePolarization(photonPolarization1);
594                                                << 630 
595       // Set ejected Compton electron directio << 631      // Set ejected Compton electron direction and energy
596       G4double PhiE = std::acos(cosPhiE);      << 632      G4double PhiE = std::acos(cosPhiE);
597       G4double eDirX = sinThetaE * std::cos(ph << 633      G4double eDirX = sinThetaE * std::cos(phi+PhiE);
598       G4double eDirY = sinThetaE * std::sin(ph << 634      G4double eDirY = sinThetaE * std::sin(phi+PhiE);
599       G4double eDirZ = cosThetaE;              << 635      G4double eDirZ = cosThetaE;
600                                                << 636 
601       G4double eKineticEnergy = pEIncident - p << 637      G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
602                                                << 638 
603       G4ThreeVector eDirection(eDirX,eDirY,eDi << 639      G4ThreeVector eDirection(eDirX,eDirY,eDirZ);
604       SystemOfRefChangeElect(photonDirection0, << 640      SystemOfRefChangeElect(photonDirection0,eDirection,
605            photonPolarization0);               << 641                   photonPolarization0);
606                                                << 642 
607       G4DynamicParticle* dp = new G4DynamicPar << 643      G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),
608                  eDirection,eKineticEnergy) ;  << 644                                                    eDirection,eKineticEnergy) ;
609       fvect->push_back(dp);                    << 645      fvect->push_back(dp);
                                                   >> 646 
610     }                                             647     }
611   else                                            648   else
612     {                                             649     {
613       fParticleChange->SetProposedKineticEnerg    650       fParticleChange->SetProposedKineticEnergy(0.);
614       fParticleChange->ProposeTrackStatus(fSto    651       fParticleChange->ProposeTrackStatus(fStopAndKill);
615     }                                             652     }
616                                                   653 
617   // sample deexcitation                          654   // sample deexcitation
618   //                                              655   //
                                                   >> 656 
619   if (verboseLevel > 3) {                         657   if (verboseLevel > 3) {
620     G4cout << "Started atomic de-excitation "     658     G4cout << "Started atomic de-excitation " << fAtomDeexcitation << G4endl;
621   }                                               659   }
622                                                   660 
623   if(fAtomDeexcitation && iteration < maxDoppl    661   if(fAtomDeexcitation && iteration < maxDopplerIterations) {
624     G4int index = couple->GetIndex();             662     G4int index = couple->GetIndex();
625     if(fAtomDeexcitation->CheckDeexcitationAct    663     if(fAtomDeexcitation->CheckDeexcitationActiveRegion(index)) {
626       std::size_t nbefore = fvect->size();     << 664       size_t nbefore = fvect->size();
627       G4AtomicShellEnumerator as = G4AtomicShe    665       G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellIdx);
628       const G4AtomicShell* shell = fAtomDeexci    666       const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
629       fAtomDeexcitation->GenerateParticles(fve    667       fAtomDeexcitation->GenerateParticles(fvect, shell, Z, index);
630       std::size_t nafter = fvect->size();      << 668       size_t nafter = fvect->size();
631       if(nafter > nbefore) {                      669       if(nafter > nbefore) {
632         for (std::size_t i=nbefore; i<nafter;  << 670         for (size_t i=nbefore; i<nafter; ++i) {
633           //Check if there is enough residual     671           //Check if there is enough residual energy 
634           if (bindingE >= ((*fvect)[i])->GetKi    672           if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
635       {                                        << 673            {
636         //Ok, this is a valid secondary: keep  << 674              //Ok, this is a valid secondary: keep it
637         bindingE -= ((*fvect)[i])->GetKineticE << 675              bindingE -= ((*fvect)[i])->GetKineticEnergy();
638       }                                        << 676            }
639           else                                    677           else
640       {                                        << 678            {
641         //Invalid secondary: not enough energy << 679              //Invalid secondary: not enough energy to create it!
642         //Keep its energy in the local deposit << 680              //Keep its energy in the local deposit
643         delete (*fvect)[i];                    << 681              delete (*fvect)[i];
644         (*fvect)[i]=nullptr;                   << 682              (*fvect)[i]=0;
645       }                                        << 683            }
646         }                                         684         }
647       }                                           685       }
648     }                                             686     }
649   }                                               687   }
650                                                   688 
651   //This should never happen                      689   //This should never happen
652   if(bindingE < 0.0)                              690   if(bindingE < 0.0)
653     G4Exception("G4LowEPPolarizedComptonModel: << 691      G4Exception("G4LowEPPolarizedComptonModel::SampleSecondaries()",
654     "em2051",FatalException,"Negative local en << 692                  "em2051",FatalException,"Negative local energy deposit");
655                                                   693 
656   fParticleChange->ProposeLocalEnergyDeposit(b    694   fParticleChange->ProposeLocalEnergyDeposit(bindingE);
                                                   >> 695 
657 }                                                 696 }
658                                                   697 
659 //********************************************    698 //****************************************************************************
660                                                   699 
661 G4double                                          700 G4double
662 G4LowEPPolarizedComptonModel::ComputeScatterin    701 G4LowEPPolarizedComptonModel::ComputeScatteringFunction(G4double x, G4int Z)
663 {                                                 702 {
664   G4double value = Z;                             703   G4double value = Z;
665   if (x <= ScatFuncFitParam[Z][2]) {              704   if (x <= ScatFuncFitParam[Z][2]) {
666                                                   705 
667     G4double lgq = G4Log(x)/ln10;                 706     G4double lgq = G4Log(x)/ln10;
668                                                   707 
669     if (lgq < ScatFuncFitParam[Z][1]) {           708     if (lgq < ScatFuncFitParam[Z][1]) {
670       value = ScatFuncFitParam[Z][3] + lgq*Sca    709       value = ScatFuncFitParam[Z][3] + lgq*ScatFuncFitParam[Z][4];
671     } else {                                      710     } else {
672       value = ScatFuncFitParam[Z][5] + lgq*Sca    711       value = ScatFuncFitParam[Z][5] + lgq*ScatFuncFitParam[Z][6] +
673         lgq*lgq*ScatFuncFitParam[Z][7] + lgq*l    712         lgq*lgq*ScatFuncFitParam[Z][7] + lgq*lgq*lgq*ScatFuncFitParam[Z][8];
674     }                                             713     }
675     value = G4Exp(value*ln10);                    714     value = G4Exp(value*ln10);
676   }                                               715   }
677   return value;                                   716   return value;
678 }                                                 717 }
679                                                   718 
680                                                   719 
681 //********************************************    720 //****************************************************************************
682                                                   721 
                                                   >> 722 #include "G4AutoLock.hh"
                                                   >> 723 namespace { G4Mutex LowEPPolarizedComptonModelMutex = G4MUTEX_INITIALIZER; }
                                                   >> 724 
683 void                                              725 void
684 G4LowEPPolarizedComptonModel::InitialiseForEle    726 G4LowEPPolarizedComptonModel::InitialiseForElement(const G4ParticleDefinition*,
685                G4int Z)                        << 727                                               G4int Z)
686 {                                                 728 {
687   G4AutoLock l(&LowEPPolarizedComptonModelMute    729   G4AutoLock l(&LowEPPolarizedComptonModelMutex);
688   if(!data[Z]) { ReadData(Z); }                   730   if(!data[Z]) { ReadData(Z); }
689   l.unlock();                                     731   l.unlock();
690 }                                                 732 }
691                                                   733 
692 //********************************************    734 //****************************************************************************
693                                                   735 
694 //Fitting data to compute scattering function     736 //Fitting data to compute scattering function 
                                                   >> 737 
695 const G4double G4LowEPPolarizedComptonModel::S    738 const G4double G4LowEPPolarizedComptonModel::ScatFuncFitParam[101][9] = {
696   {  0,    0.,          0.,      0.,    0.,    << 739 {  0,    0.,          0.,      0.,    0.,       0.,     0.,     0.,    0.},
697   {  1, 6.673, 1.49968E+08, -14.352, 1.999, -1 << 740 {  1, 6.673, 1.49968E+08, -14.352, 1.999, -143.374, 50.787, -5.951, 0.2304418},
698   {  2, 6.500, 2.50035E+08, -14.215, 1.970, -5 << 741 {  2, 6.500, 2.50035E+08, -14.215, 1.970, -53.649, 13.892, -0.948, 0.006996759},
699   {  3, 6.551, 3.99945E+08, -13.555, 1.993, -6 << 742 {  3, 6.551, 3.99945E+08, -13.555, 1.993, -62.090, 21.462, -2.453, 0.093416},
700   {  4, 6.500, 5.00035E+08, -13.746, 1.998, -1 << 743 {  4, 6.500, 5.00035E+08, -13.746, 1.998, -127.906, 46.491, -5.614, 0.2262103},
701   {  5, 6.500, 5.99791E+08, -13.800, 1.998, -1 << 744 {  5, 6.500, 5.99791E+08, -13.800, 1.998, -131.153, 47.132, -5.619, 0.2233819},
702   {  6, 6.708, 6.99842E+08, -13.885, 1.999, -1 << 745 {  6, 6.708, 6.99842E+08, -13.885, 1.999, -128.143, 45.379, -5.325, 0.2083009},
703   {  7, 6.685, 7.99834E+08, -13.885, 2.000, -1 << 746 {  7, 6.685, 7.99834E+08, -13.885, 2.000, -131.048, 46.314, -5.421, 0.2114925},
704   {  8, 6.669, 7.99834E+08, -13.962, 2.001, -1 << 747 {  8, 6.669, 7.99834E+08, -13.962, 2.001, -128.225, 44.818, -5.183, 0.1997155},
705   {  9, 6.711, 7.99834E+08, -13.999, 2.000, -1 << 748 {  9, 6.711, 7.99834E+08, -13.999, 2.000, -122.112, 42.103, -4.796, 0.1819099},
706   { 10, 6.702, 7.99834E+08, -14.044, 1.999, -1 << 749 { 10, 6.702, 7.99834E+08, -14.044, 1.999, -110.143, 37.225, -4.143, 0.1532094},
707   { 11, 6.425, 1.00000E+09, -13.423, 1.993, -4 << 750 { 11, 6.425, 1.00000E+09, -13.423, 1.993, -41.137, 12.313, -1.152, 0.03384553},
708   { 12, 6.542, 1.00000E+09, -13.389, 1.997, -5 << 751 { 12, 6.542, 1.00000E+09, -13.389, 1.997, -53.549, 17.420, -1.840, 0.06431849},
709   { 13, 6.570, 1.49968E+09, -13.401, 1.997, -6 << 752 { 13, 6.570, 1.49968E+09, -13.401, 1.997, -66.243, 22.297, -2.460, 0.09045854},
710   { 14, 6.364, 1.49968E+09, -13.452, 1.999, -7 << 753 { 14, 6.364, 1.49968E+09, -13.452, 1.999, -78.271, 26.757, -3.008, 0.1128195},
711   { 15, 6.500, 1.49968E+09, -13.488, 1.998, -8 << 754 { 15, 6.500, 1.49968E+09, -13.488, 1.998, -85.069, 29.164, -3.291, 0.1239113},
712   { 16, 6.500, 1.49968E+09, -13.532, 1.998, -9 << 755 { 16, 6.500, 1.49968E+09, -13.532, 1.998, -93.640, 32.274, -3.665, 0.1388633},
713   { 17, 6.500, 1.49968E+09, -13.584, 2.000, -9 << 756 { 17, 6.500, 1.49968E+09, -13.584, 2.000, -98.534, 33.958, -3.857, 0.1461557},
714   { 18, 6.500, 1.49968E+09, -13.618, 1.999, -1 << 757 { 18, 6.500, 1.49968E+09, -13.618, 1.999, -100.077, 34.379, -3.891, 0.1468902},
715   { 19, 6.500, 1.99986E+09, -13.185, 1.992, -5 << 758 { 19, 6.500, 1.99986E+09, -13.185, 1.992, -53.819, 17.528, -1.851, 0.0648722},
716   { 20, 6.490, 1.99986E+09, -13.123, 1.993, -5 << 759 { 20, 6.490, 1.99986E+09, -13.123, 1.993, -52.221, 17.169, -1.832, 0.06502094},
717   { 21, 6.498, 1.99986E+09, -13.157, 1.994, -5 << 760 { 21, 6.498, 1.99986E+09, -13.157, 1.994, -55.365, 18.276, -1.961, 0.07002778},
718   { 22, 6.495, 1.99986E+09, -13.183, 1.994, -5 << 761 { 22, 6.495, 1.99986E+09, -13.183, 1.994, -57.412, 18.957, -2.036, 0.07278856},
719   { 23, 6.487, 1.99986E+09, -13.216, 1.995, -5 << 762 { 23, 6.487, 1.99986E+09, -13.216, 1.995, -58.478, 19.270, -2.065, 0.07362722},
720   { 24, 6.500, 1.99986E+09, -13.330, 1.997, -6 << 763 { 24, 6.500, 1.99986E+09, -13.330, 1.997, -62.192, 20.358, -2.167, 0.07666583},
721   { 25, 6.488, 1.99986E+09, -13.277, 1.997, -5 << 764 { 25, 6.488, 1.99986E+09, -13.277, 1.997, -58.007, 18.924, -2.003, 0.0704305},
722   { 26, 6.500, 5.00035E+09, -13.292, 1.997, -6 << 765 { 26, 6.500, 5.00035E+09, -13.292, 1.997, -61.176, 20.067, -2.141, 0.0760269},
723   { 27, 6.500, 5.00035E+09, -13.321, 1.998, -6 << 766 { 27, 6.500, 5.00035E+09, -13.321, 1.998, -61.909, 20.271, -2.159, 0.07653559},
724   { 28, 6.500, 5.00035E+09, -13.340, 1.998, -6 << 767 { 28, 6.500, 5.00035E+09, -13.340, 1.998, -62.402, 20.391, -2.167, 0.07664243},
725   { 29, 6.500, 5.00035E+09, -13.439, 1.998, -6 << 768 { 29, 6.500, 5.00035E+09, -13.439, 1.998, -67.305, 21.954, -2.331, 0.0823267},
726   { 30, 6.500, 5.00035E+09, -13.383, 1.999, -6 << 769 { 30, 6.500, 5.00035E+09, -13.383, 1.999, -62.064, 20.136, -2.122, 0.07437589},
727   { 31, 6.500, 5.00035E+09, -13.349, 1.997, -6 << 770 { 31, 6.500, 5.00035E+09, -13.349, 1.997, -61.068, 19.808, -2.086, 0.07307488},
728   { 32, 6.500, 5.00035E+09, -13.373, 1.999, -6 << 771 { 32, 6.500, 5.00035E+09, -13.373, 1.999, -63.126, 20.553, -2.175, 0.07660222},
729   { 33, 6.500, 5.00035E+09, -13.395, 1.999, -6 << 772 { 33, 6.500, 5.00035E+09, -13.395, 1.999, -65.674, 21.445, -2.278, 0.08054694},
730   { 34, 6.500, 5.00035E+09, -13.417, 1.999, -6 << 773 { 34, 6.500, 5.00035E+09, -13.417, 1.999, -69.457, 22.811, -2.442, 0.08709536},
731   { 35, 6.500, 5.00035E+09, -13.442, 2.000, -7 << 774 { 35, 6.500, 5.00035E+09, -13.442, 2.000, -72.283, 23.808, -2.558, 0.09156808},
732   { 36, 6.500, 5.00035E+09, -13.451, 1.998, -7 << 775 { 36, 6.500, 5.00035E+09, -13.451, 1.998, -74.696, 24.641, -2.653, 0.09516597},
733   { 37, 6.500, 5.00035E+09, -13.082, 1.991, -4 << 776 { 37, 6.500, 5.00035E+09, -13.082, 1.991, -46.235, 14.519, -1.458, 0.04837659},
734   { 38, 6.465, 5.00035E+09, -13.022, 1.993, -4 << 777 { 38, 6.465, 5.00035E+09, -13.022, 1.993, -41.784, 13.065, -1.300, 0.04267703},
735   { 39, 6.492, 5.00035E+09, -13.043, 1.994, -4 << 778 { 39, 6.492, 5.00035E+09, -13.043, 1.994, -44.609, 14.114, -1.429, 0.0479348},
736   { 40, 6.499, 5.00035E+09, -13.064, 1.994, -4 << 779 { 40, 6.499, 5.00035E+09, -13.064, 1.994, -47.142, 15.019, -1.536, 0.0521347},
737   { 41, 6.384, 5.00035E+09, -13.156, 1.996, -5 << 780 { 41, 6.384, 5.00035E+09, -13.156, 1.996, -53.114, 17.052, -1.766, 0.06079426},
738   { 42, 6.500, 5.00035E+09, -13.176, 1.996, -5 << 781 { 42, 6.500, 5.00035E+09, -13.176, 1.996, -54.590, 17.550, -1.822, 0.06290335},
739   { 43, 6.500, 5.00035E+09, -13.133, 1.997, -5 << 782 { 43, 6.500, 5.00035E+09, -13.133, 1.997, -51.272, 16.423, -1.694, 0.05806108},
740   { 44, 6.500, 5.00035E+09, -13.220, 1.996, -5 << 783 { 44, 6.500, 5.00035E+09, -13.220, 1.996, -58.314, 18.839, -1.969, 0.0684608},
741   { 45, 6.500, 5.00035E+09, -13.246, 1.998, -5 << 784 { 45, 6.500, 5.00035E+09, -13.246, 1.998, -59.674, 19.295, -2.020, 0.07037294},
742   { 46, 6.500, 5.00035E+09, -13.407, 1.999, -7 << 785 { 46, 6.500, 5.00035E+09, -13.407, 1.999, -72.228, 23.693, -2.532, 0.09017969},
743   { 47, 6.500, 5.00035E+09, -13.277, 1.998, -6 << 786 { 47, 6.500, 5.00035E+09, -13.277, 1.998, -60.890, 19.647, -2.053, 0.07138694},
744   { 48, 6.500, 5.00035E+09, -13.222, 1.998, -5 << 787 { 48, 6.500, 5.00035E+09, -13.222, 1.998, -56.152, 18.002, -1.863, 0.06410123},
745   { 49, 6.500, 5.00035E+09, -13.199, 1.997, -5 << 788 { 49, 6.500, 5.00035E+09, -13.199, 1.997, -56.208, 18.052, -1.872, 0.06456884},
746   { 50, 6.500, 5.00035E+09, -13.215, 1.998, -5 << 789 { 50, 6.500, 5.00035E+09, -13.215, 1.998, -58.478, 18.887, -1.973, 0.06860356},
747   { 51, 6.500, 5.00035E+09, -13.230, 1.998, -6 << 790 { 51, 6.500, 5.00035E+09, -13.230, 1.998, -60.708, 19.676, -2.066, 0.07225841},
748   { 52, 6.500, 7.99834E+09, -13.246, 1.998, -6 << 791 { 52, 6.500, 7.99834E+09, -13.246, 1.998, -63.341, 20.632, -2.180, 0.0767412},
749   { 53, 6.500, 5.00035E+09, -13.262, 1.998, -6 << 792 { 53, 6.500, 5.00035E+09, -13.262, 1.998, -66.339, 21.716, -2.310, 0.08191981},
750   { 54, 6.500, 7.99834E+09, -13.279, 1.998, -6 << 793 { 54, 6.500, 7.99834E+09, -13.279, 1.998, -67.649, 22.151, -2.357, 0.08357825},
751   { 55, 6.500, 5.00035E+09, -12.951, 1.990, -4 << 794 { 55, 6.500, 5.00035E+09, -12.951, 1.990, -45.302, 14.219, -1.423, 0.04712317},
752   { 56, 6.425, 5.00035E+09, -12.882, 1.992, -3 << 795 { 56, 6.425, 5.00035E+09, -12.882, 1.992, -39.825, 12.363, -1.214, 0.03931009},
753   { 57, 6.466, 2.82488E+09, -12.903, 1.992, -3 << 796 { 57, 6.466, 2.82488E+09, -12.903, 1.992, -38.952, 11.982, -1.160, 0.03681554},
754   { 58, 6.451, 5.00035E+09, -12.915, 1.993, -4 << 797 { 58, 6.451, 5.00035E+09, -12.915, 1.993, -41.959, 13.118, -1.302, 0.04271291},
755   { 59, 6.434, 5.00035E+09, -12.914, 1.993, -4 << 798 { 59, 6.434, 5.00035E+09, -12.914, 1.993, -40.528, 12.555, -1.230, 0.03971407},
756   { 60, 6.444, 5.00035E+09, -12.922, 1.992, -3 << 799 { 60, 6.444, 5.00035E+09, -12.922, 1.992, -39.986, 12.329, -1.200, 0.03843737},
757   { 61, 6.414, 7.99834E+09, -12.930, 1.993, -4 << 800 { 61, 6.414, 7.99834E+09, -12.930, 1.993, -42.756, 13.362, -1.327, 0.0436124},
758   { 62, 6.420, 7.99834E+09, -12.938, 1.992, -4 << 801 { 62, 6.420, 7.99834E+09, -12.938, 1.992, -42.682, 13.314, -1.319, 0.04322509},
759   { 63, 6.416, 7.99834E+09, -12.946, 1.993, -4 << 802 { 63, 6.416, 7.99834E+09, -12.946, 1.993, -42.399, 13.185, -1.301, 0.04243861},
760   { 64, 6.443, 7.99834E+09, -12.963, 1.993, -4 << 803 { 64, 6.443, 7.99834E+09, -12.963, 1.993, -43.226, 13.475, -1.335, 0.04377341},
761   { 65, 6.449, 7.99834E+09, -12.973, 1.993, -4 << 804 { 65, 6.449, 7.99834E+09, -12.973, 1.993, -43.232, 13.456, -1.330, 0.04347536},
762   { 66, 6.419, 7.99834E+09, -12.966, 1.993, -4 << 805 { 66, 6.419, 7.99834E+09, -12.966, 1.993, -42.047, 12.990, -1.270, 0.04095499},
763   { 67, 6.406, 7.99834E+09, -12.976, 1.993, -4 << 806 { 67, 6.406, 7.99834E+09, -12.976, 1.993, -42.405, 13.106, -1.283, 0.04146024},
764   { 68, 6.424, 7.99834E+09, -12.986, 1.993, -4 << 807 { 68, 6.424, 7.99834E+09, -12.986, 1.993, -41.974, 12.926, -1.259, 0.040435},
765   { 69, 6.417, 7.99834E+09, -12.989, 1.993, -4 << 808 { 69, 6.417, 7.99834E+09, -12.989, 1.993, -42.132, 12.967, -1.262, 0.04048908},
766   { 70, 6.405, 7.99834E+09, -13.000, 1.994, -4 << 809 { 70, 6.405, 7.99834E+09, -13.000, 1.994, -42.582, 13.122, -1.280, 0.04119599},
767   { 71, 6.449, 7.99834E+09, -13.015, 1.994, -4 << 810 { 71, 6.449, 7.99834E+09, -13.015, 1.994, -42.586, 13.115, -1.278, 0.04107587},
768   { 72, 6.465, 7.99834E+09, -13.030, 1.994, -4 << 811 { 72, 6.465, 7.99834E+09, -13.030, 1.994, -43.708, 13.509, -1.324, 0.04286491},
769   { 73, 6.447, 7.99834E+09, -13.048, 1.996, -4 << 812 { 73, 6.447, 7.99834E+09, -13.048, 1.996, -44.838, 13.902, -1.369, 0.04457132},
770   { 74, 6.452, 7.99834E+09, -13.073, 1.997, -4 << 813 { 74, 6.452, 7.99834E+09, -13.073, 1.997, -45.545, 14.137, -1.395, 0.04553459},
771   { 75, 6.432, 7.99834E+09, -13.082, 1.997, -4 << 814 { 75, 6.432, 7.99834E+09, -13.082, 1.997, -46.426, 14.431, -1.428, 0.04678218},
772   { 76, 6.439, 7.99834E+09, -13.100, 1.997, -4 << 815 { 76, 6.439, 7.99834E+09, -13.100, 1.997, -47.513, 14.806, -1.471, 0.04842566},
773   { 77, 6.432, 7.99834E+09, -13.110, 1.997, -4 << 816 { 77, 6.432, 7.99834E+09, -13.110, 1.997, -48.225, 15.042, -1.497, 0.04938364},
774   { 78, 6.500, 7.99834E+09, -13.185, 1.997, -5 << 817 { 78, 6.500, 7.99834E+09, -13.185, 1.997, -53.256, 16.739, -1.687, 0.05645173},
775   { 79, 6.500, 7.99834E+09, -13.200, 1.997, -5 << 818 { 79, 6.500, 7.99834E+09, -13.200, 1.997, -53.900, 16.946, -1.709, 0.05723134},
776   { 80, 6.500, 7.99834E+09, -13.156, 1.998, -4 << 819 { 80, 6.500, 7.99834E+09, -13.156, 1.998, -49.801, 15.536, -1.547, 0.05103522},
777   { 81, 6.500, 7.99834E+09, -13.128, 1.997, -4 << 820 { 81, 6.500, 7.99834E+09, -13.128, 1.997, -49.651, 15.512, -1.548, 0.05123203},
778   { 82, 6.500, 7.99834E+09, -13.134, 1.997, -5 << 821 { 82, 6.500, 7.99834E+09, -13.134, 1.997, -51.021, 16.018, -1.609, 0.05364831},
779   { 83, 6.500, 7.99834E+09, -13.148, 1.998, -5 << 822 { 83, 6.500, 7.99834E+09, -13.148, 1.998, -52.693, 16.612, -1.679, 0.05638698},
780   { 84, 6.500, 7.99834E+09, -13.161, 1.998, -5 << 823 { 84, 6.500, 7.99834E+09, -13.161, 1.998, -54.415, 17.238, -1.754, 0.05935566},
781   { 85, 6.500, 7.99834E+09, -13.175, 1.998, -5 << 824 { 85, 6.500, 7.99834E+09, -13.175, 1.998, -56.083, 17.834, -1.824, 0.06206068},
782   { 86, 6.500, 7.99834E+09, -13.189, 1.998, -5 << 825 { 86, 6.500, 7.99834E+09, -13.189, 1.998, -57.860, 18.463, -1.898, 0.0649633},
783   { 87, 6.500, 7.99834E+09, -12.885, 1.990, -3 << 826 { 87, 6.500, 7.99834E+09, -12.885, 1.990, -39.973, 12.164, -1.162, 0.0364598},
784   { 88, 6.417, 7.99834E+09, -12.816, 1.991, -3 << 827 { 88, 6.417, 7.99834E+09, -12.816, 1.991, -34.591, 10.338, -0.956, 0.0287409},
785   { 89, 6.442, 7.99834E+09, -12.831, 1.992, -3 << 828 { 89, 6.442, 7.99834E+09, -12.831, 1.992, -36.002, 10.867, -1.021, 0.03136835},
786   { 90, 6.463, 7.99834E+09, -12.850, 1.993, -3 << 829 { 90, 6.463, 7.99834E+09, -12.850, 1.993, -37.660, 11.475, -1.095, 0.03435334},
787   { 91, 6.447, 7.99834E+09, -12.852, 1.993, -3 << 830 { 91, 6.447, 7.99834E+09, -12.852, 1.993, -37.268, 11.301, -1.071, 0.0330539},
788   { 92, 6.439, 7.99834E+09, -12.858, 1.993, -3 << 831 { 92, 6.439, 7.99834E+09, -12.858, 1.993, -37.695, 11.438, -1.085, 0.03376669},
789   { 93, 6.437, 1.00000E+10, -12.866, 1.993, -3 << 832 { 93, 6.437, 1.00000E+10, -12.866, 1.993, -39.010, 11.927, -1.146, 0.03630848},
790   { 94, 6.432, 7.99834E+09, -12.862, 1.993, -3 << 833 { 94, 6.432, 7.99834E+09, -12.862, 1.993, -37.192, 11.229, -1.057, 0.0325621},
791   { 95, 6.435, 7.99834E+09, -12.869, 1.993, -3 << 834 { 95, 6.435, 7.99834E+09, -12.869, 1.993, -37.589, 11.363, -1.072, 0.03312393},
792   { 96, 6.449, 1.00000E+10, -12.886, 1.993, -3 << 835 { 96, 6.449, 1.00000E+10, -12.886, 1.993, -39.573, 12.095, -1.162, 0.03680527},
793   { 97, 6.446, 1.00000E+10, -12.892, 1.993, -4 << 836 { 97, 6.446, 1.00000E+10, -12.892, 1.993, -40.007, 12.242, -1.178, 0.03737377},
794   { 98, 6.421, 1.00000E+10, -12.887, 1.993, -3 << 837 { 98, 6.421, 1.00000E+10, -12.887, 1.993, -39.509, 12.041, -1.152, 0.03629023},
795   { 99, 6.414, 1.00000E+10, -12.894, 1.993, -3 << 838 { 99, 6.414, 1.00000E+10, -12.894, 1.993, -39.939, 12.183, -1.168, 0.03690464},
796   {100, 6.412, 1.00000E+10, -12.900, 1.993, -3 << 839 {100, 6.412, 1.00000E+10, -12.900, 1.993, -39.973, 12.180, -1.166, 0.036773}
797 };                                             << 840   };
798                                                   841 
799 //********************************************    842 //****************************************************************************
800                                                   843 
801 //Supporting functions for photon polarisation    844 //Supporting functions for photon polarisation effects
                                                   >> 845 
802 G4double G4LowEPPolarizedComptonModel::SetPhi(    846 G4double G4LowEPPolarizedComptonModel::SetPhi(G4double energyRate,
803                 G4double sinT2)                << 847                                              G4double sinT2)
804 {                                                 848 {
805   G4double rand1;                                 849   G4double rand1;
806   G4double rand2;                                 850   G4double rand2;
807   G4double phiProbability;                        851   G4double phiProbability;
808   G4double phi;                                   852   G4double phi;
809   G4double a, b;                                  853   G4double a, b;
810                                                   854 
811   do                                              855   do
812     {                                             856     {
813       rand1 = G4UniformRand();                    857       rand1 = G4UniformRand();
814       rand2 = G4UniformRand();                    858       rand2 = G4UniformRand();
815       phiProbability=0.;                          859       phiProbability=0.;
816       phi = twopi*rand1;                          860       phi = twopi*rand1;
817                                                   861 
818       a = 2*sinT2;                                862       a = 2*sinT2;
819       b = energyRate + 1/energyRate;              863       b = energyRate + 1/energyRate;
820                                                   864 
821       phiProbability = 1 - (a/b)*(std::cos(phi    865       phiProbability = 1 - (a/b)*(std::cos(phi)*std::cos(phi));
                                                   >> 866 
                                                   >> 867 
                                                   >> 868 
822     }                                             869     }
823   while ( rand2 > phiProbability );               870   while ( rand2 > phiProbability );
824   return phi;                                     871   return phi;
825 }                                                 872 }
826                                                   873 
827 //********************************************    874 //****************************************************************************
828                                                   875 
829 G4ThreeVector G4LowEPPolarizedComptonModel::Se    876 G4ThreeVector G4LowEPPolarizedComptonModel::SetPerpendicularVector(G4ThreeVector& a)
830 {                                                 877 {
831   G4double dx = a.x();                            878   G4double dx = a.x();
832   G4double dy = a.y();                            879   G4double dy = a.y();
833   G4double dz = a.z();                            880   G4double dz = a.z();
834   G4double x = dx < 0.0 ? -dx : dx;               881   G4double x = dx < 0.0 ? -dx : dx;
835   G4double y = dy < 0.0 ? -dy : dy;               882   G4double y = dy < 0.0 ? -dy : dy;
836   G4double z = dz < 0.0 ? -dz : dz;               883   G4double z = dz < 0.0 ? -dz : dz;
837   if (x < y) {                                    884   if (x < y) {
838     return x < z ? G4ThreeVector(-dy,dx,0) : G    885     return x < z ? G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
839   }else{                                          886   }else{
840     return y < z ? G4ThreeVector(dz,0,-dx) : G    887     return y < z ? G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
841   }                                               888   }
842 }                                                 889 }
843                                                   890 
844 //********************************************    891 //****************************************************************************
845                                                   892 
846 G4ThreeVector G4LowEPPolarizedComptonModel::Ge    893 G4ThreeVector G4LowEPPolarizedComptonModel::GetRandomPolarization(G4ThreeVector& direction0)
847 {                                                 894 {
848   G4ThreeVector d0 = direction0.unit();           895   G4ThreeVector d0 = direction0.unit();
849   G4ThreeVector a1 = SetPerpendicularVector(d0    896   G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
850   G4ThreeVector a0 = a1.unit(); // unit vector    897   G4ThreeVector a0 = a1.unit(); // unit vector
851                                                   898 
852   G4double rand1 = G4UniformRand();               899   G4double rand1 = G4UniformRand();
853                                                   900 
854   G4double angle = twopi*rand1; // random pola    901   G4double angle = twopi*rand1; // random polar angle
855   G4ThreeVector b0 = d0.cross(a0); // cross pr    902   G4ThreeVector b0 = d0.cross(a0); // cross product
856                                                   903 
857   G4ThreeVector c;                                904   G4ThreeVector c;
858                                                   905 
859   c.setX(std::cos(angle)*(a0.x())+std::sin(ang    906   c.setX(std::cos(angle)*(a0.x())+std::sin(angle)*b0.x());
860   c.setY(std::cos(angle)*(a0.y())+std::sin(ang    907   c.setY(std::cos(angle)*(a0.y())+std::sin(angle)*b0.y());
861   c.setZ(std::cos(angle)*(a0.z())+std::sin(ang    908   c.setZ(std::cos(angle)*(a0.z())+std::sin(angle)*b0.z());
862                                                   909 
863   G4ThreeVector c0 = c.unit();                    910   G4ThreeVector c0 = c.unit();
864                                                   911 
865   return c0;                                      912   return c0;
                                                   >> 913 
866 }                                                 914 }
867                                                   915 
868 //********************************************    916 //****************************************************************************
869                                                   917 
870 G4ThreeVector G4LowEPPolarizedComptonModel::Ge    918 G4ThreeVector G4LowEPPolarizedComptonModel::GetPerpendicularPolarization
871 (const G4ThreeVector& photonDirection, const G    919 (const G4ThreeVector& photonDirection, const G4ThreeVector& photonPolarization) const
872 {                                                 920 {
                                                   >> 921 
873   //                                              922   // 
874   // The polarization of a photon is always pe    923   // The polarization of a photon is always perpendicular to its momentum direction.
875   // Therefore this function removes those vec    924   // Therefore this function removes those vector component of photonPolarization, which
876   // points in direction of photonDirection       925   // points in direction of photonDirection
877   //                                              926   //
878   // Mathematically we search the projection o    927   // Mathematically we search the projection of the vector a on the plane E, where n is the
879   // plains normal vector.                        928   // plains normal vector.
880   // The basic equation can be found in each g    929   // The basic equation can be found in each geometry book (e.g. Bronstein):
881   // p = a - (a o n)/(n o n)*n                    930   // p = a - (a o n)/(n o n)*n
882                                                   931 
883   return photonPolarization - photonPolarizati    932   return photonPolarization - photonPolarization.dot(photonDirection)/photonDirection.dot(photonDirection) * photonDirection;
884 }                                                 933 }
885                                                   934 
886 //********************************************    935 //****************************************************************************
887                                                   936 
888 G4ThreeVector G4LowEPPolarizedComptonModel::Se    937 G4ThreeVector G4LowEPPolarizedComptonModel::SetNewPolarization(G4double LowEPPCepsilon,
889                      G4double sinT2,           << 938                                                               G4double sinT2,
890                      G4double phi,             << 939                                                               G4double phi,
891                      G4double costheta)        << 940                                                               G4double costheta)
892 {                                                 941 {
893   G4double rand1;                                 942   G4double rand1;
894   G4double rand2;                                 943   G4double rand2;
895   G4double cosPhi = std::cos(phi);                944   G4double cosPhi = std::cos(phi);
896   G4double sinPhi = std::sin(phi);                945   G4double sinPhi = std::sin(phi);
897   G4double sinTheta = std::sqrt(sinT2);           946   G4double sinTheta = std::sqrt(sinT2);
898   G4double cosP2 = cosPhi*cosPhi;                 947   G4double cosP2 = cosPhi*cosPhi;
899   G4double normalisation = std::sqrt(1. - cosP    948   G4double normalisation = std::sqrt(1. - cosP2*sinT2);
900                                                   949 
                                                   >> 950 
901   // Method based on:                             951   // Method based on:
902   // D. Xu, Z. He and F. Zhang                    952   // D. Xu, Z. He and F. Zhang
903   // "Detection of Gamma Ray Polarization Usin    953   // "Detection of Gamma Ray Polarization Using a 3-D Position Sensitive CdZnTe Detector"
904   // IEEE TNS, Vol. 52(4), 1160-1164, 2005.       954   // IEEE TNS, Vol. 52(4), 1160-1164, 2005.
905                                                   955 
906   // Determination of Theta                       956   // Determination of Theta 
907                                                   957 
908   G4double theta;                                 958   G4double theta;
                                                   >> 959 
909   rand1 = G4UniformRand();                        960   rand1 = G4UniformRand();
910   rand2 = G4UniformRand();                        961   rand2 = G4UniformRand();
911                                                   962 
912   if (rand1<(LowEPPCepsilon+1.0/LowEPPCepsilon    963   if (rand1<(LowEPPCepsilon+1.0/LowEPPCepsilon-2)/(2.0*(LowEPPCepsilon+1.0/LowEPPCepsilon)-4.0*sinT2*cosP2))
913     {                                             964     {
914       if (rand2<0.5)                              965       if (rand2<0.5)
915         theta = pi/2.0;                           966         theta = pi/2.0;
916       else                                        967       else
917         theta = 3.0*pi/2.0;                       968         theta = 3.0*pi/2.0;
918     }                                             969     }
919   else                                            970   else
920     {                                             971     {
921       if (rand2<0.5)                              972       if (rand2<0.5)
922         theta = 0;                                973         theta = 0;
923       else                                        974       else
924         theta = pi;                               975         theta = pi;
925     }                                             976     }
926   G4double cosBeta = std::cos(theta);             977   G4double cosBeta = std::cos(theta);
927   G4double sinBeta = std::sqrt(1-cosBeta*cosBe    978   G4double sinBeta = std::sqrt(1-cosBeta*cosBeta);
928                                                   979 
929   G4ThreeVector photonPolarization1;              980   G4ThreeVector photonPolarization1;
930                                                   981 
931   G4double xParallel = normalisation*cosBeta;     982   G4double xParallel = normalisation*cosBeta;
932   G4double yParallel = -(sinT2*cosPhi*sinPhi)*    983   G4double yParallel = -(sinT2*cosPhi*sinPhi)*cosBeta/normalisation;
933   G4double zParallel = -(costheta*sinTheta*cos    984   G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
934   G4double xPerpendicular = 0.;                   985   G4double xPerpendicular = 0.;
935   G4double yPerpendicular = (costheta)*sinBeta    986   G4double yPerpendicular = (costheta)*sinBeta/normalisation;
936   G4double zPerpendicular = -(sinTheta*sinPhi)    987   G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
937                                                   988 
938   G4double xTotal = (xParallel + xPerpendicula    989   G4double xTotal = (xParallel + xPerpendicular);
939   G4double yTotal = (yParallel + yPerpendicula    990   G4double yTotal = (yParallel + yPerpendicular);
940   G4double zTotal = (zParallel + zPerpendicula    991   G4double zTotal = (zParallel + zPerpendicular);
941                                                   992 
942   photonPolarization1.setX(xTotal);               993   photonPolarization1.setX(xTotal);
943   photonPolarization1.setY(yTotal);               994   photonPolarization1.setY(yTotal);
944   photonPolarization1.setZ(zTotal);               995   photonPolarization1.setZ(zTotal);
945                                                   996 
946   return photonPolarization1;                     997   return photonPolarization1;
947                                                   998 
948 }                                                 999 }
949                                                << 
950 //******************************************** << 
951 void G4LowEPPolarizedComptonModel::SystemOfRef    1000 void G4LowEPPolarizedComptonModel::SystemOfRefChange(G4ThreeVector& direction0,
952                  G4ThreeVector& direction1,    << 1001                                                     G4ThreeVector& direction1,
953                  G4ThreeVector& polarization0, << 1002                                                     G4ThreeVector& polarization0,
954                  G4ThreeVector& polarization1) << 1003                                                     G4ThreeVector& polarization1)
955 {                                                 1004 {
956   // direction0 is the original photon directi    1005   // direction0 is the original photon direction ---> z
957   // polarization0 is the original photon pola    1006   // polarization0 is the original photon polarization ---> x
958   // need to specify y axis in the real refere    1007   // need to specify y axis in the real reference frame ---> y 
959   G4ThreeVector Axis_Z0 = direction0.unit();      1008   G4ThreeVector Axis_Z0 = direction0.unit();
960   G4ThreeVector Axis_X0 = polarization0.unit()    1009   G4ThreeVector Axis_X0 = polarization0.unit();
961   G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_    1010   G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_X0)).unit(); // to be confirmed;
962                                                   1011 
963   G4double direction_x = direction1.getX();       1012   G4double direction_x = direction1.getX();
964   G4double direction_y = direction1.getY();       1013   G4double direction_y = direction1.getY();
965   G4double direction_z = direction1.getZ();       1014   G4double direction_z = direction1.getZ();
966                                                   1015   
967   direction1 = (direction_x*Axis_X0 + directio    1016   direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
968   G4double polarization_x = polarization1.getX    1017   G4double polarization_x = polarization1.getX();
969   G4double polarization_y = polarization1.getY    1018   G4double polarization_y = polarization1.getY();
970   G4double polarization_z = polarization1.getZ    1019   G4double polarization_z = polarization1.getZ();
971                                                   1020 
972   polarization1 = (polarization_x*Axis_X0 + po    1021   polarization1 = (polarization_x*Axis_X0 + polarization_y*Axis_Y0 + polarization_z*Axis_Z0).unit();
973                                                   1022 
974 }                                                 1023 }
975                                                   1024 
976 //******************************************** << 
977 void G4LowEPPolarizedComptonModel::SystemOfRef    1025 void G4LowEPPolarizedComptonModel::SystemOfRefChangeElect(G4ThreeVector& pdirection,
978                 G4ThreeVector& edirection,     << 1026                                                     G4ThreeVector& edirection,
979                 G4ThreeVector& ppolarization)  << 1027                                                     G4ThreeVector& ppolarization)
980 {                                                 1028 {
981   // direction0 is the original photon directi    1029   // direction0 is the original photon direction ---> z
982   // polarization0 is the original photon pola    1030   // polarization0 is the original photon polarization ---> x
983   // need to specify y axis in the real refere    1031   // need to specify y axis in the real reference frame ---> y 
984   G4ThreeVector Axis_Z0 = pdirection.unit();      1032   G4ThreeVector Axis_Z0 = pdirection.unit();
985   G4ThreeVector Axis_X0 = ppolarization.unit()    1033   G4ThreeVector Axis_X0 = ppolarization.unit();
986   G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_    1034   G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_X0)).unit(); // to be confirmed;
987                                                   1035 
988   G4double direction_x = edirection.getX();       1036   G4double direction_x = edirection.getX();
989   G4double direction_y = edirection.getY();       1037   G4double direction_y = edirection.getY();
990   G4double direction_z = edirection.getZ();       1038   G4double direction_z = edirection.getZ();
991                                                   1039 
992   edirection = (direction_x*Axis_X0 + directio    1040   edirection = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
                                                   >> 1041 
993 }                                                 1042 }
994                                                   1043 
995                                                   1044 
996                                                   1045