Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/coherent_elastic/src/G4ElasticHadrNucleusHE.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/hadronic/models/coherent_elastic/src/G4ElasticHadrNucleusHE.cc (Version 11.3.0) and /processes/hadronic/models/coherent_elastic/src/G4ElasticHadrNucleusHE.cc (Version 4.0)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //  The generator of high energy hadron-nucleu    
 27 //  The hadron kinetic energy T > 1 GeV           
 28 //  N.Starkov 2003.                               
 29 //                                                
 30 //  19.11.05 The HE elastic scattering on prot    
 31 //  16.11.06 The low energy boundary is shifte    
 32 //  23.11.06 General cleanup, ONQ0=3, use poin    
 33 //  02.05.07 Scale sampled t as p^2 (VI)          
 34 //  15.05.07 Redesign and cleanup (V.Ivanchenk    
 35 //  17.05.07 cleanup (V.Grichine)                 
 36 //  19.04.12 Fixed reproducibility violation (    
 37 //  12.06.12 Fixed warnings of shadowed variab    
 38 //                                                
 39                                                   
 40 #include  "G4ElasticHadrNucleusHE.hh"             
 41 #include  "G4PhysicalConstants.hh"                
 42 #include  "G4SystemOfUnits.hh"                    
 43 #include  "Randomize.hh"                          
 44 #include  "G4ios.hh"                              
 45 #include  "G4ParticleTable.hh"                    
 46 #include  "G4NucleiProperties.hh"                 
 47 #include  "G4IonTable.hh"                         
 48 #include  "G4Proton.hh"                           
 49 #include  "G4PionPlus.hh"                         
 50 #include  "G4PionMinus.hh"                        
 51 #include  "G4NistManager.hh"                      
 52 #include  "G4ProductionCutsTable.hh"              
 53 #include  "G4MaterialCutsCouple.hh"               
 54 #include  "G4Material.hh"                         
 55 #include  "G4Element.hh"                          
 56 #include  "G4Log.hh"                              
 57 #include  "G4Exp.hh"                              
 58                                                   
 59 using namespace std;                              
 60                                                   
 61 const G4int G4ElasticHadrNucleusHE::fHadronCod    
 62 {211,-211,2112,2212,321,-321,130,310,311,-311,    
 63  3122,3222,3112,3212,3312,3322,3334,              
 64  -2212,-2112,-3122,-3222,-3112,-3212,-3312,-33    
 65                                                   
 66 const G4int G4ElasticHadrNucleusHE::fHadronTyp    
 67 {2,3,6,0,4,5,4,4,4,5,                             
 68  0,0,0,0,0,0,0,                                   
 69  1,7,1,1,1,1,1,1,1};                              
 70                                                   
 71 const G4int G4ElasticHadrNucleusHE::fHadronTyp    
 72 {3,4,1,0,5,6,5,5,5,6,                             
 73  0,0,0,0,0,0,0,                                   
 74  2,2,2,2,2,2,2,2,2};                              
 75                                                   
 76 G4double G4ElasticHadrNucleusHE::fLineF[]  = {    
 77 G4double G4ElasticHadrNucleusHE::fEnergy[] = {    
 78 G4double G4ElasticHadrNucleusHE::fLowEdgeEnerg    
 79 G4double G4ElasticHadrNucleusHE::fBinom[240][2    
 80                                                   
 81 G4ElasticData*                                    
 82 G4ElasticHadrNucleusHE::fElasticData[NHADRONS]    
 83                                                   
 84 #ifdef G4MULTITHREADED                            
 85   G4Mutex G4ElasticHadrNucleusHE::elasticMutex    
 86 #endif                                            
 87                                                   
 88 G4bool G4ElasticHadrNucleusHE::fStoreToFile =     
 89 G4bool G4ElasticHadrNucleusHE::fRetrieveFromFi    
 90                                                   
 91 const G4double invGeV    =  1.0/CLHEP::GeV;       
 92 const G4double MbToGeV2  =  2.568;                
 93 const G4double GeV2      =  CLHEP::GeV*CLHEP::    
 94 const G4double invGeV2   =  1.0/GeV2;             
 95 const G4double protonM   =  CLHEP::proton_mass    
 96 const G4double protonM2  =  protonM*protonM;      
 97                                                   
 98 //////////////////////////////////////////////    
 99                                                   
100 G4ElasticData::G4ElasticData(const G4ParticleD    
101            G4int Z, G4int A, const G4double* e    
102 {                                                 
103   G4double massGeV  = p->GetPDGMass()*invGeV;     
104   G4double mass2GeV2= massGeV*massGeV;            
105                                                   
106   DefineNucleusParameters(A);                     
107   G4double limitQ2 = 35./(R1*R1);     //  (GeV    
108                                                   
109   massA  = G4NucleiProperties::GetNuclearMass(    
110   massA2 = massA*massA;                           
111   /*                                              
112   G4cout << " G4ElasticData for " << p->GetPar    
113    << " Z= " << Z << " A= " << A << " R1= " <<    
114    << " R2= " << R2 << G4endl;                    
115   */                                              
116   for(G4int kk = 0; kk<NENERGY; ++kk)             
117   {                                               
118     G4double elab = e[kk] + massGeV;              
119     G4double plab2= e[kk]*(e[kk] + 2.0*massGeV    
120     G4double Q2m  = 4.0*plab2*massA2/(mass2GeV    
121                                                   
122     if(Z == 1 && p == G4Proton::Proton()) { Q2    
123                                                   
124     maxQ2[kk] = Q2m;                              
125     /*                                            
126     G4cout << " Ekin= " << e[kk] << " Q2m= " <    
127      << " limitQ2= " << limitQ2 << G4endl;        
128     */                                            
129   }                                               
130                                                   
131   dQ2 = limitQ2/(G4double)(ONQ2-2);               
132 }                                                 
133                                                   
134 //////////////////////////////////////////////    
135                                                   
136 void G4ElasticData::DefineNucleusParameters(G4    
137 {                                                 
138   switch (A) {                                    
139     case 207:                                     
140     case 208:                                     
141       R1       = 20.5;                            
142       R2       = 15.74;                           
143       Pnucl    = 0.4;                             
144       Aeff     = 0.7;                             
145       break;                                      
146     case 237:                                     
147     case 238:                                     
148       R1       = 21.7;                            
149       R2       = 16.5;                            
150       Pnucl    = 0.4;                             
151       Aeff     = 0.7;                             
152       break;                                      
153     case 90:                                      
154     case 91:                                      
155       R1    = 16.5;                               
156       R2    = 11.62;                              
157       Pnucl = 0.4;                                
158       Aeff  = 0.7;                                
159       break;                                      
160     case 58:                                      
161     case 59:                                      
162       R1    = 15.75;                              
163       R2    = 9.9;                                
164       Pnucl = 0.45;                               
165       Aeff  = 0.85;                               
166       break;                                      
167     case 48:                                      
168     case 47:                                      
169       R1    = 14.0;                               
170       R2    = 9.26;                               
171       Pnucl = 0.31;                               
172       Aeff  = 0.75;                               
173       break;                                      
174     case 40:                                      
175     case 41:                                      
176       R1    = 13.3;                               
177       R2    = 9.26;                               
178       Pnucl = 0.31;                               
179       Aeff  = 0.75;                               
180       break;                                      
181     case 28:                                      
182     case 29:                                      
183       R1    = 12.0;                               
184       R2    = 7.64;                               
185       Pnucl = 0.253;                              
186       Aeff  = 0.8;                                
187       break;                                      
188     case 16:                                      
189       R1    = 10.50;                              
190       R2    = 5.5;                                
191       Pnucl = 0.7;                                
192       Aeff  = 0.98;                               
193       break;                                      
194     case 12:                                      
195       R1    = 9.3936;                             
196       R2    = 4.63;                               
197       Pnucl = 0.7;                                
198       Aeff  = 1.0;                                
199       break;                                      
200     case 11:                                      
201       R1    = 9.0;                                
202       R2    = 5.42;                               
203       Pnucl = 0.19;                               
204       Aeff  = 0.9;                                
205       break;                                      
206     case 9:                                       
207       R1    = 9.9;                                
208       R2    = 6.5;                                
209       Pnucl = 0.690;                              
210       Aeff  = 0.95;                               
211       break;                                      
212     case 4:                                       
213       R1    = 5.3;                                
214       R2    = 3.7;                                
215       Pnucl = 0.4;                                
216       Aeff  = 0.75;                               
217       break;                                      
218     case 1:                                       
219       R1    = 4.5;                                
220       R2    = 2.3;                                
221       Pnucl = 0.177;                              
222       Aeff  = 0.9;                                
223       break;                                      
224     default:                                      
225       R1    = 4.45*G4Exp(G4Log((G4double)(A -     
226       R2    = 2.3 *G4Exp(G4Log((G4double)A)* 0    
227                                                   
228       if(A < 100 && A > 3) { Pnucl = 0.176 + 0    
229       else                 { Pnucl = 0.4; }       
230       //G4cout<<" Deault: A= "<<A<<"  R1 R2 Ae    
231       //      <<Aeff<<"  "<<Pnucl<<G4endl;        
232                                                   
233       if(A >= 100)               { Aeff = 0.7;    
234       else if(A < 100 && A > 75) { Aeff = 1.5     
235       else                       { Aeff = 0.9;    
236       break;                                      
237   }                                               
238   //G4cout<<" Result: A= "<<A<<"  R1 R2 Aeff P    
239   //      <<Aeff<<"  "<<Pnucl<<G4endl;            
240 }                                                 
241                                                   
242 //////////////////////////////////////////////    
243                                                   
244 G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE    
245   : G4HadronElastic(name), fDirectory(nullptr)    
246 {                                                 
247   dQ2 = hMass = hMass2 = hLabMomentum = hLabMo    
248     = R1 = R2 = Pnucl = Aeff = HadrTot = HadrS    
249     = DDSect3 = ConstU = Slope1 = Slope2 = Coe    
250     = Slope0 = Coeff0 = aAIm = aDIm = Dtot11 =    
251   iHadrCode = iHadron = iHadron1 = 0;             
252                                                   
253   verboseLevel = 0;                               
254   ekinLowLimit = 400.0*CLHEP::MeV;                
255                                                   
256   BoundaryP[0]=9.0; BoundaryTG[0]=5.0;Boundary    
257   BoundaryP[1]=20.0;BoundaryTG[1]=1.5;Boundary    
258   BoundaryP[2]=5.0; BoundaryTG[2]=1.0;Boundary    
259   BoundaryP[3]=8.0; BoundaryTG[3]=3.0;Boundary    
260   BoundaryP[4]=7.0; BoundaryTG[4]=3.0;Boundary    
261   BoundaryP[5]=5.0; BoundaryTG[5]=2.0;Boundary    
262   BoundaryP[6]=5.0; BoundaryTG[6]=1.5;Boundary    
263                                                   
264   nistManager = G4NistManager::Instance();        
265                                                   
266   if(fEnergy[0] == 0.0) {                         
267 #ifdef G4MULTITHREADED                            
268     G4MUTEXLOCK(&elasticMutex);                   
269     if(fEnergy[0] == 0.0) {                       
270 #endif                                            
271       isMaster = true;                            
272       Binom();                                    
273       // energy in GeV                            
274       fEnergy[0] = 0.4;                           
275       fEnergy[1] = 0.6;                           
276       fEnergy[2] = 0.8;                           
277       fEnergy[3] = 1.0;                           
278       fLowEdgeEnergy[0] = 0.0;                    
279       fLowEdgeEnergy[1] = 0.5;                    
280       fLowEdgeEnergy[2] = 0.7;                    
281       fLowEdgeEnergy[3] = 0.9;                    
282       G4double f = G4Exp(G4Log(10.)*0.1);         
283       G4double e = f*f;                           
284       for(G4int i=4; i<NENERGY; ++i) {            
285   fEnergy[i] = e;                                 
286   fLowEdgeEnergy[i] = e/f;                        
287   e *= f*f;                                       
288       }                                           
289       if(verboseLevel > 0) {                      
290   G4cout << "### G4ElasticHadrNucleusHE: energ    
291   for(G4int i=0; i<NENERGY; ++i) {                
292     G4cout << "  " << i << "   " << fLowEdgeEn    
293      << "  " << fEnergy[i] << G4endl;             
294   }                                               
295       }                                           
296 #ifdef G4MULTITHREADED                            
297     }                                             
298     G4MUTEXUNLOCK(&elasticMutex);                 
299 #endif                                            
300   }                                               
301 }                                                 
302                                                   
303 //////////////////////////////////////////////    
304                                                   
305 void G4ElasticHadrNucleusHE::ModelDescription(    
306 {                                                 
307   outFile << "G4ElasticHadrNucleusHE is a hadr    
308     << "model developed by N. Starkov which us    
309     << "parameterization to calculate the fina    
310     << "for all hadrons with incident momentum    
311 }                                                 
312                                                   
313 //////////////////////////////////////////////    
314                                                   
315 G4ElasticHadrNucleusHE::~G4ElasticHadrNucleusH    
316 {                                                 
317   if(isMaster) {                                  
318     for(G4int j = 0; j < NHADRONS; ++j) {         
319       for(G4int k = 0; k < ZMAX; ++k) {           
320   G4ElasticData* ptr = fElasticData[j][k];        
321   if(ptr) {                                       
322     delete ptr;                                   
323     fElasticData[j][k] = nullptr;                 
324     for(G4int l = j+1; l < NHADRONS; ++l) {       
325       if(ptr == fElasticData[l][k]) { fElastic    
326     }                                             
327   }                                               
328       }                                           
329     }                                             
330     delete fDirectory;                            
331     fDirectory = nullptr;                         
332   }                                               
333 }                                                 
334                                                   
335 //////////////////////////////////////////////    
336                                                   
337 void G4ElasticHadrNucleusHE::InitialiseModel()    
338 {                                                 
339   if(!isMaster) { return; }                       
340   G4ProductionCutsTable* theCoupleTable=          
341     G4ProductionCutsTable::GetProductionCutsTa    
342   G4int numOfCouples = (G4int)theCoupleTable->    
343                                                   
344   for(G4int i=0; i<2; ++i) {                      
345     const G4ParticleDefinition* p = G4PionPlus    
346     if(1 == i) { p = G4PionMinus::PionMinus();    
347     iHadrCode = fHadronCode[i];                   
348     iHadron   = fHadronType[i];                   
349     iHadron1  = fHadronType1[i];                  
350     hMass     = p->GetPDGMass()*invGeV;           
351     hMass2    = hMass*hMass;                      
352     for(G4int j=0; j<numOfCouples; ++j) {         
353       auto mat = theCoupleTable->GetMaterialCu    
354       auto elmVec = mat->GetElementVector();      
355       std::size_t numOfElem = mat->GetNumberOf    
356       for(std::size_t k=0; k<numOfElem; ++k) {    
357         G4int Z = std::min((*elmVec)[k]->GetZa    
358         if(!fElasticData[i][Z]) {                 
359           if(1 == i && Z > 1) {                   
360             fElasticData[1][Z] = fElasticData[    
361           } else {                                
362             FillData(p, i, Z);                    
363           }                                       
364         }                                         
365       }                                           
366     }                                             
367   }                                               
368 }                                                 
369                                                   
370 //////////////////////////////////////////////    
371                                                   
372 G4double                                          
373 G4ElasticHadrNucleusHE::SampleInvariantT(const    
374            G4double inLabMom,                     
375            G4int iZ, G4int A)                     
376 {                                                 
377   G4double mass = p->GetPDGMass();                
378   G4double kine = sqrt(inLabMom*inLabMom + mas    
379   if(kine <= ekinLowLimit) {                      
380     return G4HadronElastic::SampleInvariantT(p    
381   }                                               
382   G4int Z = std::min(iZ,ZMAX-1);                  
383   G4double Q2 = 0.0;                              
384   iHadrCode = p->GetPDGEncoding();                
385                                                   
386   // below computations in GeV/c                  
387   hMass  = mass*invGeV;                           
388   hMass2 = hMass*hMass;                           
389   G4double plab = inLabMom*invGeV;                
390   G4double tmax = pLocalTmax*invGeV2;             
391                                                   
392   if(verboseLevel > 1) {                          
393     G4cout<< "G4ElasticHadrNucleusHE::SampleT:    
394     << " for " << p->GetParticleName()            
395     << " at Z= " << Z << " A= " << A              
396     << " plab(GeV)= " << plab                     
397     << " hadrCode= " << iHadrCode                 
398     << G4endl;                                    
399   }                                               
400   iHadron = -1;                                   
401   G4int idx;                                      
402   for(idx=0; idx<NHADRONS; ++idx) {               
403     if(iHadrCode == fHadronCode[idx]) {           
404       iHadron = fHadronType[idx];                 
405       iHadron1 = fHadronType1[idx];               
406       break;                                      
407     }                                             
408   }                                               
409   // Hadron is not in the list                    
410   if(0 > iHadron) { return 0.0; }                 
411                                                   
412   if(Z==1) {                                      
413     Q2 = HadronProtonQ2(plab, tmax);              
414                                                   
415     if (verboseLevel>1) {                         
416       G4cout<<"  Proton : Q2  "<<Q2<<G4endl;      
417     }                                             
418   } else {                                        
419     const G4ElasticData* ElD1 = fElasticData[i    
420                                                   
421     // Construct elastic data                     
422     if(!ElD1) {                                   
423       FillData(p, idx, Z);                        
424       ElD1 = fElasticData[idx][Z];                
425       if(!ElD1) { return 0.0; }                   
426     }                                             
427                                                   
428     // sample scattering                          
429     Q2 = HadronNucleusQ2_2(ElD1, plab, tmax);     
430                                                   
431     if(verboseLevel > 1) {                        
432       G4cout<<" SampleT: Q2(GeV^2)= "<<Q2<< "     
433             << Q2/tmax <<G4endl;                  
434     }                                             
435   }                                               
436   return Q2*GeV2;                                 
437 }                                                 
438                                                   
439 //////////////////////////////////////////////    
440                                                   
441 void G4ElasticHadrNucleusHE::FillData(const G4    
442                                       G4int id    
443 {                                                 
444 #ifdef G4MULTITHREADED                            
445   G4MUTEXLOCK(&elasticMutex);                     
446   if(!fElasticData[idx][Z]) {                     
447 #endif                                            
448     G4int A = G4lrint(nistManager->GetAtomicMa    
449     G4ElasticData* pElD = new G4ElasticData(p,    
450     if(fRetrieveFromFile) {                       
451       std::ostringstream ss;                      
452       InFileName(ss, p, Z);                       
453       std::ifstream infile(ss.str(), std::ios:    
454       for(G4int i=0; i<NENERGY; ++i) {            
455   if(ReadLine(infile, pElD->fCumProb[i])) {       
456     continue;                                     
457   } else {                                        
458     fRetrieveFromFile = false;                    
459           break;                                  
460   }                                               
461       }                                           
462       infile.close();                             
463     }                                             
464     R1     = pElD->R1;                            
465     R2     = pElD->R2;                            
466     Aeff   = pElD->Aeff;                          
467     Pnucl  = pElD->Pnucl;                         
468     dQ2    = pElD->dQ2;                           
469     if(verboseLevel > 0) {                        
470       G4cout<<"### FillData for " << p->GetPar    
471       << " Z= " << Z << " idx= " << idx << " i    
472       <<" iHadron1= " << iHadron1 << " iHadrCo    
473             <<"\n   R1= " << R1 << " R2= " <<     
474       <<" Pnucl= " << Pnucl << G4endl;            
475     }                                             
476                                                   
477     if(!fRetrieveFromFile) {                      
478       for(G4int i=0; i<NENERGY; ++i) {            
479   G4double T = fEnergy[i];                        
480   hLabMomentum2 = T*(T + 2.*hMass);               
481   hLabMomentum  = std::sqrt(hLabMomentum2);       
482   HadrEnergy = hMass + T;                         
483   DefineHadronValues(Z);                          
484   Q2max = pElD->maxQ2[i];                         
485                                                   
486   G4int length  = FillFq2(A);                     
487   (pElD->fCumProb[i]).reserve(length);            
488   G4double norm = 1.0/fLineF[length-1];           
489                                                   
490   if(verboseLevel > 0) {                          
491     G4cout << "### i= " << i << " Z= " << Z <<    
492      << " length= " << length << " Q2max= " <<    
493   }                                               
494                                                   
495   (pElD->fCumProb[i]).push_back(0.0);             
496   for(G4int ii=1; ii<length-1; ++ii) {            
497     (pElD->fCumProb[i]).push_back(fLineF[ii]*n    
498     if(verboseLevel > 2) {                        
499       G4cout << "    ii= " << ii << " val= "      
500        << (pElD->fCumProb[i])[ii] << G4endl;      
501     }                                             
502   }                                               
503   (pElD->fCumProb[i]).push_back(1.0);             
504       }                                           
505     }                                             
506                                                   
507     if(fStoreToFile) {                            
508       std::ostringstream ss;                      
509       OutFileName(ss, p, Z);                      
510       std::ofstream fileout(ss.str());            
511       for(G4int i=0; i<NENERGY; ++i) {            
512   WriteLine(fileout, pElD->fCumProb[i]);          
513       }                                           
514       fileout.close();                            
515     }                                             
516                                                   
517     if(verboseLevel > 0) {                        
518       G4cout << " G4ElasticHadrNucleusHE::Fill    
519        << " for " << p->GetParticleName() << "    
520        << " A= " << A << G4endl;                  
521     }                                             
522     fElasticData[idx][Z] = pElD;                  
523                                                   
524 #ifdef G4MULTITHREADED                            
525   }                                               
526   G4MUTEXUNLOCK(&elasticMutex);                   
527 #endif                                            
528 }                                                 
529                                                   
530 //////////////////////////////////////////////    
531                                                   
532 void G4ElasticHadrNucleusHE::InterpolateHN(G4i    
533                    const G4double C0P[], const    
534                    const G4double B0P[], const    
535 {                                                 
536   G4int i;                                        
537                                                   
538   for(i=1; i<n; ++i) { if(hLabMomentum <= EnP[    
539   if(i == n) { i = n - 1; }                       
540                                                   
541   Coeff0 = LineInterpol(EnP[i], EnP[i-1], C0P[    
542   Coeff1 = LineInterpol(EnP[i], EnP[i-1], C1P[    
543   Slope0 = LineInterpol(EnP[i], EnP[i-1], B0P[    
544   Slope1 = LineInterpol(EnP[i], EnP[i-1], B1P[    
545                                                   
546 //  G4cout<<"  InterpolHN:  n i "<<n<<"  "<<i<    
547 //        <<hLabMomentum<<G4endl;                 
548 }                                                 
549                                                   
550 //////////////////////////////////////////////    
551                                                   
552 G4double                                          
553 G4ElasticHadrNucleusHE::HadronNucleusQ2_2(cons    
554                                           G4do    
555 {                                                 
556   G4double ekin  = std::sqrt(hMass2 + plab*pla    
557                                                   
558   if(verboseLevel > 1) {                          
559     G4cout<<"Q2_2: ekin(GeV)= " << ekin << "      
560           <<"  tmax(GeV2)= " << tmax <<G4endl;    
561   }                                               
562   // Find closest energy bin                      
563   G4int idx;                                      
564   for(idx=0; idx<NENERGY-1; ++idx) {              
565     if(ekin <= fLowEdgeEnergy[idx+1]) { break;    
566   }                                               
567   //G4cout << "   idx= " << idx << G4endl;        
568                                                   
569   // Select kinematics for node energy            
570   R1    = pElD->R1;                               
571   dQ2   = pElD->dQ2;                              
572   Q2max = pElD->maxQ2[idx];                       
573   G4int length = (G4int)(pElD->fCumProb[idx]).    
574                                                   
575   G4double Rand = G4UniformRand();                
576                                                   
577   G4int iNumbQ2 = 0;                              
578   for(iNumbQ2=1; iNumbQ2<length; ++iNumbQ2) {     
579     if(Rand <= (pElD->fCumProb[idx])[iNumbQ2])    
580   }                                               
581   iNumbQ2 = std::min(iNumbQ2, length - 1);        
582   G4double Q2 = GetQ2_2(iNumbQ2, length, pElD-    
583   Q2 = std::min(Q2, Q2max);                       
584   Q2 *= tmax/Q2max;                               
585                                                   
586   if(verboseLevel > 1) {                          
587     G4cout<<" HadrNucleusQ2_2(2): Q2= "<<Q2<<"    
588     << " rand= " << Rand << " Q2max= " << Q2ma    
589           << " tmax= " << tmax << G4endl;         
590   }                                               
591   return Q2;                                      
592 }                                                 
593                                                   
594 //////////////////////////////////////////////    
595 //                                                
596 //  The randomization of one dimensional array    
597 //                                                
598                                                   
599 G4double G4ElasticHadrNucleusHE::GetQ2_2(G4int    
600            const std::vector<G4double>& F,        
601                                          G4dou    
602 {                                                 
603   //G4cout << "GetQ2_2 kk= " << kk << " kmax=     
604   //   << F.size() << "  rand= " << ranUni <<     
605   if(kk == kmax-1) {                              
606     G4double X1 = dQ2*kk;                         
607     G4double F1 = F[kk-1];                        
608     G4double X2 = Q2max;                          
609     G4double xx = R1*(X2 - X1);                   
610     xx = (xx > 20.) ? 0.0 : G4Exp(-xx);           
611     G4double Y = X1 - G4Log(1.0 - (ranUni - F1    
612     return Y;                                     
613   }                                               
614   G4double F1, F2, F3, X1, X2, X3;                
615                                                   
616   if(kk == 1 || kk == 0) {                        
617     F1 = F[0];                                    
618     F2 = F[1];                                    
619     F3 = F[2];                                    
620     X1 = 0.0;                                     
621     X2 = dQ2;                                     
622     X3 = dQ2*2;                                   
623   } else {                                        
624     F1 = F[kk-2];                                 
625     F2 = F[kk-1];                                 
626     F3 = F[kk];                                   
627     X1 = dQ2*(kk-2);                              
628     X2 = dQ2*(kk-1);                              
629     X3 = dQ2*kk;                                  
630   }                                               
631   if(verboseLevel > 1) {                          
632     G4cout << "GetQ2_2 kk= " << kk << " X2= "     
633      << " F2= " << F2 << " F3= " << F3 << " Rn    
634   }                                               
635                                                   
636   G4double F12 = F1*F1;                           
637   G4double F22 = F2*F2;                           
638   G4double F32 = F3*F3;                           
639                                                   
640   G4double D0  = F12*F2+F1*F32+F3*F22-F32*F2-F    
641                                                   
642   if(verboseLevel > 2) {                          
643     G4cout << "       X1= " << X1 << " F1= " <    
644            << D0 << G4endl;                       
645   }                                               
646   G4double Y;                                     
647   if(std::abs(D0) < 1.e-9) {                      
648     Y = X2 + (ranUni - F2)*(X3 - X2)/(F3 - F2)    
649   } else {                                        
650     G4double DA = X1*F2+X3*F1+X2*F3-X3*F2-X1*F    
651     G4double DB = X2*F12+X1*F32+X3*F22-X2*F32-    
652     G4double DC = X3*F2*F12+X2*F1*F32+X1*F3*F2    
653              -X1*F2*F32-X2*F3*F12-X3*F1*F22;      
654     Y = (DA*ranUni*ranUni + DB*ranUni + DC)/D0    
655   }                                               
656   return Y;                                       
657 }                                                 
658                                                   
659 //////////////////////////////////////////////    
660                                                   
661 G4int G4ElasticHadrNucleusHE::FillFq2(G4int A)    
662 {                                                 
663   G4double curQ2, curSec;                         
664   G4double curSum = 0.0;                          
665   G4double totSum = 0.0;                          
666                                                   
667   G4double ddQ2 = dQ2*0.1;                        
668   G4double Q2l  = 0.0;                            
669                                                   
670   G4int ii = 0;                                   
671   for(ii=1; ii<ONQ2-1; ++ii) {                    
672     curSum = curSec = 0.0;                        
673                                                   
674     for(G4int jj=0; jj<10; ++jj) {                
675       curQ2 = Q2l+(jj + 0.5)*ddQ2;                
676       if(curQ2 >= Q2max) { break; }               
677       curSec = HadrNucDifferCrSec(A, curQ2);      
678       curSum += curSec;                           
679     }                                             
680     G4double del = (curQ2 >= Q2max) ? Q2max -     
681     Q2l    += del;                                
682     curSum *= del*0.1;                            
683     totSum += curSum;                             
684     fLineF[ii] = totSum;                          
685     if (verboseLevel>2) {                         
686       G4cout<<ii << ". FillFq2: A= " << A << "    
687       <<dQ2<<" Tot= "<<totSum << " dTot " <<cu    
688       <<" curSec= " <<curSec<<G4endl;             
689     }                                             
690     if(totSum*1.e-4 > curSum || Q2l >= Q2max)     
691   }                                               
692   ii = std::min(ii, ONQ2-2);                      
693   curQ2 = Q2l;                                    
694   G4double xx = R1*(Q2max - curQ2);               
695   if(xx > 0.0) {                                  
696     xx = (xx > 20.) ? 0.0 : G4Exp(-xx);           
697     curSec = HadrNucDifferCrSec(A, curQ2);        
698     totSum += curSec*(1.0 - xx)/R1;               
699   }                                               
700   fLineF[ii + 1] = totSum;                        
701   if (verboseLevel>1) {                           
702     G4cout << "### FillFq2 done curQ2= " << cu    
703            << " sumG= " << fLineF[ONQ2-2] << "    
704      << " Nbins= " << ii + 1 << G4endl;           
705   }                                               
706   return ii + 2;                                  
707 }                                                 
708                                                   
709 //////////////////////////////////////////////    
710                                                   
711 G4double G4ElasticHadrNucleusHE::GetLightFq2(G    
712 {                                                 
713   // Scattering off proton                        
714   if(Z == 1)                                      
715   {                                               
716     G4double SqrQ2  = std::sqrt(Q2);              
717     G4double valueConstU = 2.*(hMass2 + proton    
718                                                   
719     G4double y = (1.-Coeff1-Coeff0)/HadrSlope*    
720       + Coeff0*(1.-G4Exp(-Slope0*Q2))             
721       + Coeff2/Slope2*G4Exp(Slope2*valueConstU    
722       + 2.*Coeff1/Slope1*(1./Slope1-(1./Slope1    
723                                                   
724     return y;                                     
725   }                                               
726                                                   
727   // The preparing of probability function        
728                                                   
729   G4double prec = A > 208  ?  1.0e-7 : 1.0e-6;    
730                                                   
731   G4double    Stot     = HadrTot*MbToGeV2;        
732   G4double    Bhad     = HadrSlope;         //    
733   G4double    Asq      = 1+HadrReIm*HadrReIm;     
734   G4double    Rho2     = std::sqrt(Asq);          
735                                                   
736   if(verboseLevel >1) {                           
737     G4cout<<" Fq2 Before for i Tot B Im "<<Had    
738       <<HadrReIm<<G4endl;                         
739   }                                               
740   if(verboseLevel > 1) {                          
741     G4cout << "GetFq2: Stot= " << Stot << " Bh    
742            <<"  Im "<<HadrReIm                    
743            << " Asq= " << Asq << G4endl;          
744     G4cout << "R1= " << R1 << " R2= " << R2 <<    
745   }                                               
746   G4double    R12      = R1*R1;                   
747   G4double    R22      = R2*R2;                   
748   G4double    R12B     = R12+2*Bhad;              
749   G4double    R22B     = R22+2*Bhad;              
750                                                   
751   G4double    Norm     = (R12*R1-Pnucl*R22*R2)    
752                                                   
753   G4double    R13      = R12*R1/R12B;             
754   G4double    R23      = Pnucl*R22*R2/R22B;       
755   G4double    Unucl    = Stot/twopi*R13/Norm;     
756   G4double    UnucRho2 = -Unucl*Rho2;             
757                                                   
758   G4double    FiH      = std::asin(HadrReIm/Rh    
759   G4double    NN2      = R23/R13;                 
760                                                   
761   if(verboseLevel > 2) {                          
762     G4cout << "UnucRho2= " << UnucRho2 << " Fi    
763      << " Norm= " << Norm << G4endl;              
764   }                                               
765   G4double    Prod0 = 0.;                         
766   G4double    N1    = -1.0;                       
767                                                   
768   for(G4int i1 = 1; i1<= A; ++i1) ////++++++++    
769     {                                             
770       N1 *= (-Unucl*Rho2*(A-i1+1)/(G4double)i1    
771       G4double Prod1 = 0.;                        
772       G4double N2    = -1.;                       
773                                                   
774       for(G4int i2 = 1; i2<=A; ++i2) ////+++++    
775         {                                         
776           N2 *= (-Unucl*Rho2*(A-i2+1)/(G4doubl    
777           G4double Prod2 = 0;                     
778           G4double N5    = -1/NN2;                
779     for(G4int j2=0; j2<= i2; ++j2) ////+++++++    
780             {                                     
781               G4double Prod3 = 0;                 
782               G4double exp2  = 1./((G4double)j    
783               N5 *= (-NN2);                       
784               G4double N4 = -1./NN2;              
785         for(G4int j1=0; j1<=i1; ++j1) ////++++    
786     {                                             
787       G4double exp1  = 1./((G4double)j1/R22B+(    
788       G4double dddd  = 0.25*(exp1+exp2);          
789       N4    *= (-NN2);                            
790       Prod3 +=                                    
791                     N4*exp1*exp2*(1.-G4Exp(-Q2    
792     }                                   // j1     
793         Prod2 += Prod3*N5*GetBinomCof(i2,j2);     
794       }                                      /    
795     Prod1 += Prod2*N2*std::cos(FiH*(i1-i2));      
796                                                   
797     if (std::abs(Prod2*N2/Prod1)<prec) break;     
798         }                                         
799       Prod0 += Prod1*N1;                          
800       if(std::abs(N1*Prod1/Prod0) < prec) brea    
801     }                                             
802                                                   
803   const G4double fact = 0.25*CLHEP::pi/MbToGeV    
804   Prod0 *= fact;  //  This is in mb               
805                                                   
806   if(verboseLevel>1) {                            
807     G4cout << "GetLightFq2 Z= " << Z << " A= "    
808      <<" Q2= " << Q2 << " Res= " << Prod0 << G    
809   }                                               
810   return Prod0;                                   
811 }                                                 
812                                                   
813 //////////////////////////////////////////////    
814                                                   
815 G4double                                          
816 G4ElasticHadrNucleusHE::HadrNucDifferCrSec(G4i    
817 {                                                 
818   //   ------ All external kinematical variabl    
819   //            ------ but internal in GeV !!!    
820                                                   
821   // Scattering of proton                         
822   if(A == 1)                                      
823   {                                               
824     G4double SqrQ2  = std::sqrt(aQ2);             
825     G4double valueConstU = hMass2 + protonM2-2    
826                                                   
827     BoundaryTL[0] = Q2max;                        
828     BoundaryTL[1] = Q2max;                        
829     BoundaryTL[3] = Q2max;                        
830     BoundaryTL[4] = Q2max;                        
831     BoundaryTL[5] = Q2max;                        
832                                                   
833     G4double dSigPodT = HadrTot*HadrTot*(1+Had    
834       ( Coeff1*G4Exp(-Slope1*SqrQ2)+              
835   Coeff2*G4Exp( Slope2*(valueConstU)+aQ2)+        
836   (1-Coeff1-Coeff0)*G4Exp(-HadrSlope*aQ2)+        
837   Coeff0*G4Exp(-Slope0*aQ2) )*2.568/(16*pi);      
838                                                   
839     return dSigPodT;                              
840   }                                               
841                                                   
842   G4double    Stot     = HadrTot*MbToGeV2;        
843   G4double    Bhad     = HadrSlope;               
844   G4double    Asq      = 1+HadrReIm*HadrReIm;     
845   G4double    Rho2     = std::sqrt(Asq);          
846   G4double    R12      = R1*R1;                   
847   G4double    R22      = R2*R2;                   
848   G4double    R12B     = R12+2*Bhad;              
849   G4double    R22B     = R22+2*Bhad;              
850   G4double    R12Ap    = R12+20;                  
851   G4double    R22Ap    = R22+20;                  
852   G4double    R13Ap    = R12*R1/R12Ap;            
853   G4double    R23Ap    = R22*R2*Pnucl/R22Ap;      
854   G4double    R23dR13  = R23Ap/R13Ap;             
855   G4double    R12Apd   = 2/R12Ap;                 
856   G4double    R22Apd   = 2/R22Ap;                 
857   G4double R12ApdR22Ap = 0.5*(R12Apd+R22Apd);     
858                                                   
859   G4double DDSec1p  = (DDSect2+DDSect3*G4Log(0    
860   G4double DDSec2p  = (DDSect2+DDSect3*G4Log(0    
861                              std::sqrt((R12+R2    
862   G4double DDSec3p  = (DDSect2+DDSect3*G4Log(0    
863                                                   
864   G4double    Norm     = (R12*R1-Pnucl*R22*R2)    
865   G4double    R13      = R12*R1/R12B;             
866   G4double    R23      = Pnucl*R22*R2/R22B;       
867   G4double    Unucl    = Stot/(twopi*Norm)*R13    
868   G4double    UnuclScr = Stot/(twopi*Norm)*R13    
869   G4double    SinFi    = HadrReIm/Rho2;           
870   G4double    FiH      = std::asin(SinFi);        
871   G4double    N        = -1;                      
872   G4double    N2       = R23/R13;                 
873                                                   
874   G4double ImElasticAmpl0 = 0;                    
875   G4double ReElasticAmpl0 = 0;                    
876   G4double exp1;                                  
877                                                   
878   for(G4int i=1; i<=A; ++i) {                     
879     N  *= (-Unucl*Rho2*(A-i+1)/(G4double)i);      
880     G4double N4 = 1;                              
881     G4double medTot = R12B/(G4double)i;           
882     G4double Prod1  = G4Exp(-aQ2*R12B/(G4doubl    
883                                                   
884     for(G4int l=1; l<=i; ++l) {                   
885       exp1 = l/R22B+(i-l)/R12B;                   
886       N4 *= (-N2*(i-l+1)/(G4double)l);            
887       G4double expn4 = N4/exp1;                   
888       Prod1  += expn4*G4Exp(-aQ2/(exp1*4));       
889       medTot += expn4;                            
890     }  // end l                                   
891                                                   
892     G4double dcos = N*std::cos(FiH*i);            
893     ReElasticAmpl0  += Prod1*N*std::sin(FiH*i)    
894     ImElasticAmpl0  += Prod1*dcos;                
895     if(std::abs(Prod1*N/ImElasticAmpl0) < 0.00    
896   }      // i                                     
897                                                   
898   static const G4double pi25 = CLHEP::pi/2.568    
899   ImElasticAmpl0 *= pi25;   // The amplitude i    
900   ReElasticAmpl0 *= pi25;   // The amplitude i    
901                                                   
902   G4double C1 = R13Ap*R13Ap*0.5*DDSec1p;          
903   G4double C2 = 2*R23Ap*R13Ap*0.5*DDSec2p;        
904   G4double C3 = R23Ap*R23Ap*0.5*DDSec3p;          
905                                                   
906   G4double N1p  = 1;                              
907   G4double Din1 = 0.5*(C1*G4Exp(-aQ2/8*R12Ap)/    
908            C2/R12ApdR22Ap*G4Exp(-aQ2/(4*R12Apd    
909            C3*R22Ap/2*G4Exp(-aQ2/8*R22Ap));       
910                                                   
911   G4double DTot1 = 0.5*(C1*0.5*R12Ap-C2/R12Apd    
912                                                   
913   for(G4int i=1; i<= A-2; ++i) {                  
914     N1p *= (-UnuclScr*Rho2*(A-i-1)/(G4double)i    
915     G4double N2p  = 1;                            
916     G4double Din2 = 0;                            
917     G4double DmedTot = 0;                         
918     G4double BinCoeff = 1.0;                      
919     for(G4int l=0; l<=i; ++l) {                   
920       if(l > 0) { BinCoeff *= (i-l+1)/(G4doubl    
921                                                   
922       exp1  = l/R22B+(i-l)/R12B;                  
923       G4double exp1p = exp1+R12Apd;               
924       G4double exp2p = exp1+R12ApdR22Ap;          
925       G4double exp3p = exp1+R22Apd;               
926                                                   
927       Din2 += N2p*BinCoeff*(C1/exp1p*G4Exp(-aQ    
928           C2/exp2p*G4Exp(-aQ2/(4*exp2p))+         
929           C3/exp3p*G4Exp(-aQ2/(4*exp3p)));        
930                                                   
931       DmedTot += N2p*BinCoeff*(C1/exp1p-C2/exp    
932                                                   
933       N2p *= -R23dR13;                            
934     }     // l                                    
935                                                   
936     G4double dcos = N1p*std::cos(FiH*i)/(G4dou    
937     Din1  += Din2*dcos;                           
938     DTot1 += DmedTot*dcos;                        
939                                                   
940     if(std::abs(Din2*N1p/Din1) < 0.000001) bre    
941   }           //  i                               
942   G4double gg = (G4double)(A*(A-1)*4)/(Norm*No    
943                                                   
944   Din1  *= (-gg);                                 
945   DTot1 *= 5*gg;                                  
946                                                   
947   //  ----------------  dSigma/d|-t|,  mb/(GeV    
948                                                   
949   G4double DiffCrSec2 = (ReElasticAmpl0*ReElas    
950        (ImElasticAmpl0+Din1)*                     
951        (ImElasticAmpl0+Din1))/twopi;              
952                                                   
953   Dtot11 = DTot1;                                 
954   aAIm   = ImElasticAmpl0;                        
955   aDIm   = Din1;                                  
956                                                   
957   return DiffCrSec2;  //  dSig/d|-t|,  mb/(GeV    
958 }                                                 
959                                                   
960 //////////////////////////////////////////////    
961                                                   
962 void G4ElasticHadrNucleusHE::DefineHadronValue    
963 {                                                 
964   G4double sHadr = 2.*HadrEnergy*protonM+proto    
965   G4double sqrS  = std::sqrt(sHadr);              
966                                                   
967   if(verboseLevel>2) {                            
968     G4cout << "GetHadrValues: Z= " << Z << " i    
969      << " E(GeV)= " << HadrEnergy << " sqrS= "    
970      << " plab= " << hLabMomentum                 
971      <<"  E - m  "<<HadrEnergy - hMass<< G4end    
972   }                                               
973   G4double TotN = 0.0;                            
974   G4double logE = G4Log(HadrEnergy);              
975   G4double logS = G4Log(sHadr);                   
976            TotP = 0.0;                            
977                                                   
978   switch (iHadron) {                              
979   case 0:                  //  proton, neutron    
980   case 6:                                         
981                                                   
982     if(hLabMomentum > 10) {                       
983       TotP = TotN = 7.5*logE - 40.12525 + 103*    
984                                                   
985     } else {                                      
986       // ==================  neutron  ========    
987                                                   
988       if( hLabMomentum > 1.4 ) {                  
989   TotN = 33.3+15.2*(hLabMomentum2-1.35)/          
990     (G4Exp(G4Log(hLabMomentum)*2.37)+0.95);       
991                                                   
992       } else if(hLabMomentum > 0.8) {             
993   G4double A0 = logE + 0.0513;                    
994   TotN = 33.0 + 25.5*A0*A0;                       
995       } else {                                    
996   G4double A0 = logE - 0.2634;  // log(1.3)       
997   TotN = 33.0 + 30.*A0*A0*A0*A0;                  
998       }                                           
999       //  =================  proton  =========    
1000                                                  
1001       if(hLabMomentum >= 1.05) {                 
1002   TotP = 39.0+75.*(hLabMomentum-1.2)/(hLabMom    
1003       } else if(hLabMomentum >= 0.7) {           
1004   G4double A0 = logE + 0.3147;                   
1005   TotP = 23.0 + 40.*A0*A0;                       
1006       } else {                                   
1007   TotP = 23.+50.*G4Exp(G4Log(G4Log(0.73/hLabM    
1008       }                                          
1009     }                                            
1010     HadrTot = 0.5*(TotP+TotN);                   
1011     //  .....................................    
1012     //  Proton slope                             
1013     if(hLabMomentum >= 2.)       { HadrSlope     
1014     else if(hLabMomentum >= 0.5) { HadrSlope     
1015     else                         { HadrSlope     
1016                                                  
1017     //  .....................................    
1018     if(hLabMomentum >= 1.2) {                    
1019       HadrReIm  = 0.13*(logS - 5.8579332)*G4E    
1020     } else if(hLabMomentum >= 0.6) {             
1021       HadrReIm = -75.5*(G4Exp(G4Log(hLabMomen    
1022   (G4Exp(G4Log(3*hLabMomentum)*2.2)+1);          
1023     } else {                                     
1024       HadrReIm = 15.5*hLabMomentum/(27*hLabMo    
1025     }                                            
1026     //  .....................................    
1027     DDSect2   = 2.2;                             
1028     DDSect3   = 0.6;                             
1029     //  ================== lambda  ==========    
1030     if( iHadrCode == 3122) {                     
1031       HadrTot   *= 0.88;                         
1032       HadrSlope *=0.85;                          
1033       //  ================== sigma +  =======    
1034     } else if( iHadrCode == 3222) {              
1035       HadrTot   *=0.81;                          
1036       HadrSlope *=0.85;                          
1037       //  ================== sigma 0,-  =====    
1038     } else if(iHadrCode == 3112 || iHadrCode     
1039       HadrTot   *=0.88;                          
1040       HadrSlope *=0.85;                          
1041       //  ===================  xi  ==========    
1042     } else if( iHadrCode == 3312 || iHadrCode    
1043       HadrTot   *=0.77;                          
1044       HadrSlope *=0.75;                          
1045       //  =================  omega  =========    
1046     } else if( iHadrCode == 3334) {              
1047       HadrTot   *=0.78;                          
1048       HadrSlope *=0.7;                           
1049     }                                            
1050     break;                                       
1051     //  =====================================    
1052   case 1:              //   antiproton           
1053   case 7:              //   antineutron          
1054                                                  
1055     HadrTot   = 5.2+5.2*logE + 123.2/sqrS;       
1056     HadrSlope = 8.32+0.57*logS;                  
1057                                                  
1058     if( HadrEnergy < 1000 ) {                    
1059       HadrReIm  = 0.06*(sqrS-2.236)*(sqrS-14.    
1060     } else {                                     
1061       HadrReIm  = 0.6*(logS - 5.8579332)*G4Ex    
1062     }                                            
1063     DDSect2   = 11;                              
1064     DDSect3   = 3;                               
1065     //  ================== lambda  ==========    
1066     if( iHadrCode == -3122) {                    
1067       HadrTot   *= 0.88;                         
1068       HadrSlope *=0.85;                          
1069       //  ================== sigma +  =======    
1070     } else if( iHadrCode == -3222) {             
1071       HadrTot   *=0.81;                          
1072       HadrSlope *=0.85;                          
1073       //  ================== sigma 0,-  =====    
1074     } else if(iHadrCode == -3112 || iHadrCode    
1075       HadrTot   *=0.88;                          
1076       HadrSlope *=0.85;                          
1077     //  ===================  xi  ============    
1078     } else if( iHadrCode == -3312 || iHadrCod    
1079       HadrTot   *=0.77;                          
1080       HadrSlope *=0.75;                          
1081       //  =================  omega  =========    
1082     } else if( iHadrCode == -3334) {             
1083       HadrTot   *=0.78;                          
1084       HadrSlope *=0.7;                           
1085     }                                            
1086     break;                                       
1087     //  -------------------------------------    
1088   case 2:             //   pi plus, pi minus     
1089   case 3:                                        
1090                                                  
1091     if(hLabMomentum >= 3.5) {                    
1092       TotP = 10.6+2.*logE + 25.*G4Exp(-logE*0    
1093       //  ===================================    
1094     } else if(hLabMomentum >= 1.15) {            
1095       G4double x = (hLabMomentum - 2.55)/0.55    
1096       G4double y = (hLabMomentum - 1.47)/0.22    
1097       TotP = 3.2*G4Exp(-x*x) + 12.*G4Exp(-y*y    
1098       //  ===================================    
1099     } else if(hLabMomentum >= 0.4) {             
1100       TotP  = 88*(logE+0.2877)*(logE+0.2877)+    
1101     //  =====================================    
1102     } else {                                     
1103       G4double x = (hLabMomentum - 0.29)/0.08    
1104       TotP = 20. + 180.*G4Exp(-x*x);             
1105     }                                            
1106     //  -------------------------------------    
1107                                                  
1108     if(hLabMomentum >= 3.0 ) {                   
1109       TotN = 10.6 + 2.*logE + 30.*G4Exp(-logE    
1110     } else if(hLabMomentum >= 1.3) {             
1111       G4double x = (hLabMomentum - 2.1)/0.4;     
1112       G4double y = (hLabMomentum - 1.4)/0.12;    
1113       TotN = 36.1+0.079 - 4.313*logE + 3.*G4E    
1114     } else if(hLabMomentum >= 0.65) {            
1115       G4double x = (hLabMomentum - 0.72)/0.06    
1116       G4double y = (hLabMomentum - 1.015)/0.0    
1117       TotN = 36.1 + 10.*G4Exp(-x*x) + 24*G4Ex    
1118     } else if(hLabMomentum >= 0.37) {            
1119       G4double x = G4Log(hLabMomentum/0.48);     
1120       TotN = 26. + 110.*x*x;                     
1121     } else {                                     
1122       G4double x = (hLabMomentum - 0.29)/0.07    
1123       TotN = 28.0 + 40.*G4Exp(-x*x);             
1124     }                                            
1125     HadrTot = (TotP+TotN)*0.5;                   
1126     //  .....................................    
1127     HadrSlope = 7.28+0.245*logS;        // Ge    
1128     HadrReIm  = 0.2*(logS - 4.6051702)*G4Exp(    
1129                                                  
1130     DDSect2   = 0.7;                             
1131     DDSect3   = 0.27;                            
1132                                                  
1133     break;                                       
1134     //  =====================================    
1135   case 4:            //  K plus                  
1136                                                  
1137     HadrTot   = 10.6+1.8*logE + 9.0*G4Exp(-lo    
1138     if(HadrEnergy>100) { HadrSlope = 15.0; }     
1139     else { HadrSlope = 1.0+1.76*logS - 2.84/s    
1140                                                  
1141     HadrReIm  = 0.4*(sHadr-20)*(sHadr-150)*G4    
1142     DDSect2   = 0.7;                             
1143     DDSect3   = 0.21;                            
1144     break;                                       
1145     //  =====================================    
1146   case 5:              //   K minus              
1147                                                  
1148     HadrTot   = 10+1.8*logE + 25./sqrS; // mb    
1149     HadrSlope = 6.98+0.127*logS;         // G    
1150     HadrReIm  = 0.4*(sHadr-20)*(sHadr-20)*G4E    
1151     DDSect2   = 0.7;                             
1152     DDSect3   = 0.27;                            
1153     break;                                       
1154   }                                              
1155   //  =======================================    
1156   if(verboseLevel>2) {                           
1157     G4cout << "HadrTot= " << HadrTot << " Had    
1158      << " HadrReIm= " << HadrReIm << " DDSect    
1159      << " DDSect3= " << DDSect3 << G4endl;       
1160   }                                              
1161   if(Z != 1) return;                             
1162                                                  
1163   // Scattering of protons                       
1164                                                  
1165   Coeff0 = Coeff1 = Coeff2 = 0.0;                
1166   Slope0 = Slope1 = 1.0;                         
1167   Slope2 = 5.0;                                  
1168                                                  
1169   // data for iHadron=0                          
1170   static const G4double EnP0[6]={1.5,3.0,5.0,    
1171   static const G4double C0P0[6]={0.15,0.02,0.    
1172   static const G4double C1P0[6]={0.05,0.02,0.    
1173   static const G4double B0P0[6]={1.5,2.5,3.0,    
1174   static const G4double B1P0[6]={5.0,1.0,3.5,    
1175                                                  
1176   // data for iHadron=6,7                        
1177   static const G4double EnN[5]={1.5,5.0,10.0,    
1178   static const G4double C0N[5]={0.0,0.0,0.02,    
1179   static const G4double C1N[5]={0.06,0.008,0.    
1180   static const G4double B0N[5]={1.5,2.5,3.8,3    
1181   static const G4double B1N[5]={1.5,2.2,3.6,4    
1182                                                  
1183   // data for iHadron=1                          
1184   static const G4double EnP[2]={1.5,4.0};        
1185   static const G4double C0P[2]={0.001,0.0005}    
1186   static const G4double C1P[2]={0.003,0.001};    
1187   static const G4double B0P[2]={2.5,4.5};        
1188   static const G4double B1P[2]={1.0,4.0};        
1189                                                  
1190   // data for iHadron=2                          
1191   static const G4double EnPP[4]={1.0,2.0,3.0,    
1192   static const G4double C0PP[4]={0.0,0.0,0.0,    
1193   static const G4double C1PP[4]={0.15,0.08,0.    
1194   static const G4double B0PP[4]={1.5,2.8,3.8,    
1195   static const G4double B1PP[4]={0.8,1.6,3.6,    
1196                                                  
1197   // data for iHadron=3                          
1198   static const G4double EnPPN[4]={1.0,2.0,3.0    
1199   static const G4double C0PPN[4]={0.0,0.0,0.0    
1200   static const G4double C1PPN[4]={0.0,0.0,0.0    
1201   static const G4double B0PPN[4]={1.5,2.8,3.8    
1202   static const G4double B1PPN[4]={0.8,1.6,3.6    
1203                                                  
1204   // data for iHadron=4                          
1205   static const G4double EnK[4]={1.4,2.33,3.0,    
1206   static const G4double C0K[4]={0.0,0.0,0.0,0    
1207   static const G4double C1K[4]={0.01,0.007,0.    
1208   static const G4double B0K[4]={1.5,2.0,3.8,3    
1209   static const G4double B1K[4]={1.6,1.6,1.6,1    
1210                                                  
1211   // data for iHadron=5                          
1212   static const G4double EnKM[2]={1.4,4.0};       
1213   static const G4double C0KM[2]={0.006,0.002}    
1214   static const G4double C1KM[2]={0.00,0.00};     
1215   static const G4double B0KM[2]={2.5,3.5};       
1216   static const G4double B1KM[2]={1.6,1.6};       
1217                                                  
1218   switch(iHadron) {                              
1219   case 0:                                        
1220                                                  
1221     if(hLabMomentum <BoundaryP[0]) {             
1222       InterpolateHN(6,EnP0,C0P0,C1P0,B0P0,B1P    
1223     }                                            
1224     Coeff2 = 0.8/hLabMomentum2;                  
1225     break;                                       
1226                                                  
1227   case 6:                                        
1228                                                  
1229     if(hLabMomentum < BoundaryP[1]) {            
1230       InterpolateHN(5,EnN,C0N,C1N,B0N,B1N);      
1231     }                                            
1232     Coeff2 = 0.8/hLabMomentum2;                  
1233     break;                                       
1234                                                  
1235   case 1:                                        
1236   case 7:                                        
1237     if(hLabMomentum <  BoundaryP[2]) {           
1238       InterpolateHN(2,EnP,C0P,C1P,B0P,B1P);      
1239     }                                            
1240     break;                                       
1241                                                  
1242   case 2:                                        
1243                                                  
1244     if(hLabMomentum < BoundaryP[3]) {            
1245       InterpolateHN(4,EnPP,C0PP,C1PP,B0PP,B1P    
1246     }                                            
1247     Coeff2 = 0.02/hLabMomentum;                  
1248     break;                                       
1249                                                  
1250   case 3:                                        
1251                                                  
1252     if(hLabMomentum < BoundaryP[4]) {            
1253       InterpolateHN(4,EnPPN,C0PPN,C1PPN,B0PPN    
1254     }                                            
1255     Coeff2 = 0.02/hLabMomentum;                  
1256     break;                                       
1257                                                  
1258   case 4:                                        
1259                                                  
1260     if(hLabMomentum < BoundaryP[5]) {            
1261       InterpolateHN(4,EnK,C0K,C1K,B0K,B1K);      
1262     }                                            
1263     if(hLabMomentum < 1) { Coeff2 = 0.34; }      
1264     else  { Coeff2 = 0.34/(hLabMomentum2*hLab    
1265     break;                                       
1266                                                  
1267   case 5:                                        
1268     if(hLabMomentum < BoundaryP[6]) {            
1269       InterpolateHN(2,EnKM,C0KM,C1KM,B0KM,B1K    
1270     }                                            
1271     if(hLabMomentum < 1) { Coeff2 = 0.01; }      
1272     else  { Coeff2 = 0.01/(hLabMomentum2*hLab    
1273     break;                                       
1274   }                                              
1275                                                  
1276   if(verboseLevel > 2) {                         
1277     G4cout<<"  HadrVal : Plasb  "<<hLabMoment    
1278     <<"  iHadron  "<<iHadron<<"  HadrTot  "<<    
1279   }                                              
1280 }                                                
1281                                                  
1282 /////////////////////////////////////////////    
1283                                                  
1284 G4double G4ElasticHadrNucleusHE::GetFt(G4doub    
1285 {                                                
1286   G4double Fdistr=0;                             
1287   G4double SqrQ2 = std::sqrt(Q2);                
1288                                                  
1289   Fdistr = (1-Coeff1-Coeff0) / HadrSlope*(1-G    
1290     + Coeff0*(1-G4Exp(-Slope0*Q2))               
1291     + Coeff2/Slope2*G4Exp(Slope2*ConstU)*(G4E    
1292     + 2*Coeff1/Slope1*(1/Slope1-(1/Slope1+Sqr    
1293                                                  
1294   if (verboseLevel>1) {                          
1295     G4cout<<"Old:  Coeff0 Coeff1 Coeff2 "<<Co    
1296           <<Coeff1<<"  "<<Coeff2<<"  Slope Sl    
1297           <<HadrSlope<<"  "<<Slope0<<"  "<<Sl    
1298           <<"  Fdistr "<<Fdistr<<G4endl;         
1299   }                                              
1300   return Fdistr;                                 
1301 }                                                
1302                                                  
1303 /////////////////////////////////////////////    
1304                                                  
1305 G4double                                         
1306 G4ElasticHadrNucleusHE::HadronProtonQ2(G4doub    
1307 {                                                
1308   hLabMomentum  = plab;                          
1309   hLabMomentum2 = hLabMomentum*hLabMomentum;     
1310   HadrEnergy    = std::sqrt(hMass2 + hLabMome    
1311   DefineHadronValues(1);                         
1312                                                  
1313   G4double Sh = 2.0*protonM*HadrEnergy+proton    
1314   ConstU = 2*protonM2+2*hMass2-Sh;               
1315                                                  
1316   BoundaryTL[0] = tmax;                          
1317   BoundaryTL[1] = tmax;                          
1318   BoundaryTL[3] = tmax;                          
1319   BoundaryTL[4] = tmax;                          
1320   BoundaryTL[5] = tmax;                          
1321                                                  
1322   G4double MaxTR = (plab < BoundaryP[iHadron1    
1323     BoundaryTL[iHadron1] : BoundaryTG[iHadron    
1324                                                  
1325   if (verboseLevel>1) {                          
1326     G4cout<<"3  GetKin. : iHadron1  "<<iHadro    
1327     <<"  Bound.P[iHadron1] "<<BoundaryP[iHadr    
1328     <<"  Bound.TL[iHadron1] "<<BoundaryTL[iHa    
1329     <<"  Bound.TG[iHadron1] "<<BoundaryTG[iHa    
1330     <<"  MaxT MaxTR "<<tmax<<"  "<<MaxTR<<G4e    
1331   }                                              
1332                                                  
1333   G4double rand = G4UniformRand();               
1334                                                  
1335   G4double DDD0=MaxTR*0.5, DDD1=0.0, DDD2=Max    
1336                                                  
1337   G4double norm  = 1.0/GetFt(MaxTR);             
1338   G4double delta = GetFt(DDD0)*norm - rand;      
1339                                                  
1340   static const G4int maxNumberOfLoops = 10000    
1341   G4int loopCounter = -1;                        
1342   while ( (std::abs(delta) > 0.0001) &&          
1343           ++loopCounter < maxNumberOfLoops )     
1344     {                                            
1345       if(delta>0)                                
1346       {                                          
1347         DDD2 = DDD0;                             
1348         DDD0 = (DDD0+DDD1)*0.5;                  
1349       }                                          
1350       else if(delta<0.0)                         
1351       {                                          
1352         DDD1 = DDD0;                             
1353         DDD0 = (DDD0+DDD2)*0.5;                  
1354       }                                          
1355       delta = GetFt(DDD0)*norm - rand;           
1356     }                                            
1357   return (loopCounter >= maxNumberOfLoops) ?     
1358 }                                                
1359                                                  
1360 /////////////////////////////////////////////    
1361                                                  
1362 void G4ElasticHadrNucleusHE::Binom()             
1363 {                                                
1364   for(G4int N = 0; N < 240; ++N) {               
1365     G4double J = 1.0;                            
1366     for(G4int M = 0; M <= N; ++M) {              
1367       G4double Fact1 = 1.0;                      
1368       if (N > 0 && N > M && M > 0 ) {            
1369   J *= (G4double)(N-M+1)/(G4double)M;            
1370   Fact1 = J;                                     
1371       }                                          
1372       fBinom[N][M] = Fact1;                      
1373     }                                            
1374   }                                              
1375 }                                                
1376                                                  
1377 /////////////////////////////////////////////    
1378                                                  
1379 void                                             
1380 G4ElasticHadrNucleusHE::InFileName(std::ostri    
1381            const G4ParticleDefinition* p, G4i    
1382 {                                                
1383   if(!fDirectory) {                              
1384     fDirectory = G4FindDataDir("G4LEDATA");      
1385     if (fDirectory) {                            
1386       ss << fDirectory << "/";                   
1387     }                                            
1388   }                                              
1389   OutFileName(ss, p, Z);                         
1390 }                                                
1391                                                  
1392 /////////////////////////////////////////////    
1393                                                  
1394 void                                             
1395 G4ElasticHadrNucleusHE::OutFileName(std::ostr    
1396             const G4ParticleDefinition* p, G4    
1397 {                                                
1398   ss << "hedata/" << p->GetParticleName() <<     
1399 }                                                
1400                                                  
1401 /////////////////////////////////////////////    
1402                                                  
1403 G4bool G4ElasticHadrNucleusHE::ReadLine(std::    
1404           std::vector<G4double>& v)              
1405 {                                                
1406   G4int n(0);                                    
1407   infile >> n;                                   
1408   if (infile.fail()) { return false; }           
1409   if(n > 0) {                                    
1410     v.reserve(n);                                
1411     G4double x(0.0);                             
1412     for(G4int i=0; i<n; ++i) {                   
1413       infile >> x;                               
1414       if (infile.fail()) { return false; }       
1415       v.emplace_back(x);                         
1416     }                                            
1417   }                                              
1418   return true;                                   
1419 }                                                
1420                                                  
1421 /////////////////////////////////////////////    
1422                                                  
1423 void G4ElasticHadrNucleusHE::WriteLine(std::o    
1424                std::vector<G4double>& v)         
1425 {                                                
1426   std::size_t n = v.size();                      
1427   outfile << n << G4endl;                        
1428   if(n > 0) {                                    
1429     for(std::size_t i=0; i<n; ++i) {             
1430       outfile << v[i] << " ";                    
1431     }                                            
1432     outfile << G4endl;                           
1433   }                                              
1434 }                                                
1435                                                  
1436 /////////////////////////////////////////////    
1437