Geant4  10.01.p03
G4QuasiElRatios.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4QuasiElRatios.cc 90573 2015-06-04 09:38:49Z gcosmo $
28 //
29 //
30 // G4 Physics class: G4QuasiElRatios for N+A elastic cross sections
31 // Created: M.V. Kossov, CERN/ITEP(Moscow), 10-OCT-01
32 // The last update: M.V. Kossov, CERN/ITEP (Moscow) 15-Oct-06
33 //
34 // ----------------------------------------------------------------------
35 // This class has been extracted from the CHIPS model.
36 // All the dependencies on CHIPS classes have been removed.
37 // Short description: Provides percentage of quasi-free and quasi-elastic
38 // reactions in the inelastic reactions.
39 // ----------------------------------------------------------------------
40 
41 
42 #include "G4QuasiElRatios.hh"
43 #include "G4PhysicalConstants.hh"
44 #include "G4SystemOfUnits.hh"
45 #include "G4Proton.hh"
46 #include "G4Neutron.hh"
47 #include "G4Deuteron.hh"
48 #include "G4Triton.hh"
49 #include "G4He3.hh"
50 #include "G4Alpha.hh"
51 #include "G4ThreeVector.hh"
53 
54 namespace {
55  const G4int nps=150; // Number of steps in the R(s) LinTable
56  const G4int mps=nps+1; // Number of elements in the R(s) LinTable
57  const G4double sma=150.; // The first LinTabEl(s=0)=1., s>sma -> logTab
58  const G4double ds=sma/nps; // Step of the linear Table
59  const G4int nls=100; // Number of steps in the R(lns) logTable
60  const G4int mls=nls+1; // Number of elements in the R(lns) logTable
61  const G4double lsi=5.; // The min ln(s) logTabEl(s=148.4 < sma=150.)
62  const G4double lsa=9.; // The max ln(s) logTabEl(s=148.4 - 8103. mb)
63  const G4double mi=std::exp(lsi);// The min s of logTabEl(~ 148.4 mb)
64  const G4double min_s=std::exp(lsa);// The max s of logTabEl(~ 8103. mb)
65  const G4double dls=(lsa-lsi)/nls;// Step of the logarithmic Table
66  const G4double edls=std::exp(dls);// Multiplication step of the logarithmic Table
67  const G4double toler=.01; // The tolarence mb defining the same cross-section
68  const G4double C=1.246;
69  const G4double lmi=3.5; // min of (lnP-lmi)^2 parabola
70  const G4double pbe=.0557; // elastic (lnP-lmi)^2 parabola coefficient
71  const G4double pbt=.3; // total (lnP-lmi)^2 parabola coefficient
72  const G4double pmi=.1; // Below that fast LE calculation is made
73  const G4double pma=1000.; // Above that fast HE calculation is made
74  const G4int nlp=300; // Number of steps in the S(lnp) logTable(5% step)
75  const G4int mlp=nlp+1; // Number of elements in the S(lnp) logTable
76  const G4double lpi=-5.; // The min ln(p) logTabEl(p=6.7 MeV/c - 22. TeV/c)
77  const G4double lpa=10.; // The max ln(p) logTabEl(p=6.7 MeV/c - 22. TeV/c)
78  const G4double mip=std::exp(lpi);// The min p of logTabEl(~ 6.7 MeV/c)
79  const G4double map=std::exp(lpa);// The max p of logTabEl(~ 22. TeV)
80  const G4double dlp=(lpa-lpi)/nlp;// Step of the logarithmic Table
81  const G4double edlp=std::exp(dlp);// Multiplication step of the logarithmic Table
82 }
83 
84 
86 {
87  vT = new std::vector<G4double*>;
88  vL = new std::vector<G4double*>;
89  vX = new std::vector<std::pair<G4double,G4double>*>;
90 
91  lastSRatio=0.; // The last sigma value for which R was calculated
92  lastRRatio=0.; // The last ratio R which was calculated
93  lastARatio=0; // theLast of calculated A
94  lastHRatio=0.; // theLast of max s initialized in the LinTable
95  lastNRatio=0; // theLast of topBin number initialized in LinTable
96  lastMRatio=0.; // theLast of rel max ln(s) initialized in LogTable
97  lastKRatio=0; // theLast of topBin number initialized in LogTable
98  lastTRatio=0; // theLast of pointer to LinTable in the C++ heap
99  lastLRatio=0; // theLast of pointer to LogTable in the C++ heap
100  lastPtot=0.; // The last momentum for which XS was calculated
101  lastHtot=0; // The last projPDG for which XS was calculated
102  lastFtot=true; // The last nucleon for which XS was calculated
103  lastItot=0; // The Last index for which XS was calculated
104  lastMtot=0.; // The Last rel max ln(p) initialized in LogTable
105  lastKtot=0; // The Last topBin number initialized in LogTable
106  lastXtot = new std::pair<G4double,G4double>; // The Last ETPointers to LogTable in heap
107 
109 
111 }
112 
114 {
115  std::vector<G4double*>::iterator pos;
116  for(pos=vT->begin(); pos<vT->end(); pos++)
117  { delete [] *pos; }
118  vT->clear();
119  for(pos=vL->begin(); pos<vL->end(); pos++)
120  { delete [] *pos; }
121  vL->clear();
122 
123  std::vector<std::pair<G4double,G4double>*>::iterator pos2;
124  for(pos2=vX->begin(); pos2<vX->end(); pos2++)
125  { delete [] *pos2; }
126  vX->clear();
127 }
128 
129 // Calculation of pair(QuasiFree/Inelastic,QuasiElastic/QuasiFree)
130 std::pair<G4double,G4double> G4QuasiElRatios::GetRatios(G4double pIU, G4int pPDG,
131  G4int tgZ, G4int tgN)
132 {
133  G4double R=0.;
134  G4double QF2In=1.; // Prototype of QuasiFree/Inel ratio for hN_tot
135  G4int tgA=tgZ+tgN;
136  if(tgA<2) return std::make_pair(QF2In,R); // No quasi-elastic on the only nucleon
137  std::pair<G4double,G4double> ElTot=GetElTot(pIU, pPDG, tgZ, tgN); // mean hN El&Tot(IU)
138  //if( ( (pPDG>999 && pIU<227.) || pIU<27.) && tgA>1) R=1.; // @@ TMP to accelerate @lowE
139  if(pPDG>999 && pIU<227. && tgZ+tgN>1) R=1.; // To accelerate @lowE
140  else if(ElTot.second>0.)
141  {
142  R=ElTot.first/ElTot.second; // El/Total ratio (does not depend on units
143  QF2In=GetQF2IN_Ratio(ElTot.second/millibarn, tgZ+tgN); // QuasiFree/Inelastic ratio
144  }
145  return std::make_pair(QF2In,R);
146 }
147 
148 // Calculatio QasiFree/Inelastic Ratio as a function of total hN cross-section (mb) and A
150 {
151  // LogTable is created only if necessary. The ratio R(s>8100 mb) = 0 for any nuclei
152  if(m_s<toler || A<2) return 1.;
153  if(m_s>min_s) return 0.;
154 
155  if(A>238)
156  {
157  G4cout<<"-Warning-G4QuasiElRatio::GetQF2IN_Ratio:A="<<A<<">238, return zero"<<G4endl;
158  return 0.;
159  }
160  G4int nDB=vARatio.size(); // A number of nuclei already initialized in AMDB
161  if(nDB && lastARatio==A && m_s==lastSRatio) return lastRRatio; // VI do not use tolerance
162  G4bool found=false;
163  G4int i=-1;
164  if(nDB) for (i=0; i<nDB; i++) if(A==vARatio[i]) // Search for this A in AMDB
165  {
166  found=true; // The A value is found
167  break;
168  }
169  if(!nDB || !found) // Create new line in the AMDB
170  {
171  lastARatio = A;
172  lastTRatio = new G4double[mps]; // Create the linear Table
173  lastNRatio = static_cast<int>(m_s/ds)+1; // MaxBin to be initialized
174  if(lastNRatio>nps)
175  {
176  lastNRatio=nps;
177  lastHRatio=sma;
178  }
179  else lastHRatio = lastNRatio*ds; // Calculate max initialized s for LinTab
180  G4double sv=0;
181  lastTRatio[0]=1.;
182  for(G4int j=1; j<=lastNRatio; j++) // Calculate LogTab values
183  {
184  sv+=ds;
185  lastTRatio[j]=CalcQF2IN_Ratio(sv,A);
186  }
187  lastLRatio=new G4double[mls]; // Create the logarithmic Table
188  if(m_s>sma) // Initialize the logarithmic Table
189  {
190  G4double ls=std::log(m_s);
191  lastKRatio = static_cast<int>((ls-lsi)/dls)+1; // MaxBin to be initialized in LogTaB
192  if(lastKRatio>nls)
193  {
194  lastKRatio=nls;
195  lastMRatio=lsa-lsi;
196  }
197  else lastMRatio = lastKRatio*dls; // Calculate max initialized ln(s)-lsi for LogTab
198  sv=mi;
199  for(G4int j=0; j<=lastKRatio; j++) // Calculate LogTab values
200  {
201  lastLRatio[j]=CalcQF2IN_Ratio(sv,A);
202  if(j!=lastKRatio) sv*=edls;
203  }
204  }
205  else // LogTab is not initialized
206  {
207  lastKRatio = 0;
208  lastMRatio = 0.;
209  }
210  i++; // Make a new record to AMDB and position on it
211  vARatio.push_back(lastARatio);
212  vHRatio.push_back(lastHRatio);
213  vNRatio.push_back(lastNRatio);
214  vMRatio.push_back(lastMRatio);
215  vKRatio.push_back(lastKRatio);
216  vT->push_back(lastTRatio);
217  vL->push_back(lastLRatio);
218  }
219  else // The A value was found in AMDB
220  {
221  lastARatio=vARatio[i];
222  lastHRatio=vHRatio[i];
223  lastNRatio=vNRatio[i];
224  lastMRatio=vMRatio[i];
225  lastKRatio=vKRatio[i];
226  lastTRatio=(*vT)[i];
227  lastLRatio=(*vL)[i];
228  if(m_s>lastHRatio) // At least LinTab must be updated
229  {
230  G4int nextN=lastNRatio+1; // The next bin to be initialized
231  if(lastNRatio<nps)
232  {
233  G4double sv=lastHRatio; // bug fix by WP
234 
235  lastNRatio = static_cast<int>(m_s/ds)+1;// MaxBin to be initialized
236  if(lastNRatio>nps)
237  {
238  lastNRatio=nps;
239  lastHRatio=sma;
240  }
241  else lastHRatio = lastNRatio*ds; // Calculate max initialized s for LinTab
242 
243  for(G4int j=nextN; j<=lastNRatio; j++)// Calculate LogTab values
244  {
245  sv+=ds;
246  lastTRatio[j]=CalcQF2IN_Ratio(sv,A);
247  }
248  } // End of LinTab update
249  if(lastNRatio>=nextN)
250  {
251  vHRatio[i]=lastHRatio;
252  vNRatio[i]=lastNRatio;
253  }
254  G4int nextK=lastKRatio+1;
255  if(!lastKRatio) nextK=0;
256  if(m_s>sma && lastKRatio<nls) // LogTab must be updated
257  {
258  G4double sv=std::exp(lastMRatio+lsi); // Define starting poit (lastM will be changed)
259  G4double ls=std::log(m_s);
260  lastKRatio = static_cast<int>((ls-lsi)/dls)+1; // MaxBin to be initialized in LogTaB
261  if(lastKRatio>nls)
262  {
263  lastKRatio=nls;
264  lastMRatio=lsa-lsi;
265  }
266  else lastMRatio = lastKRatio*dls; // Calculate max initialized ln(s)-lsi for LogTab
267  for(G4int j=nextK; j<=lastKRatio; j++)// Calculate LogTab values
268  {
269  sv*=edls;
270  lastLRatio[j]=CalcQF2IN_Ratio(sv,A);
271  }
272  } // End of LogTab update
273  if(lastKRatio>=nextK)
274  {
275  vMRatio[i]=lastMRatio;
276  vKRatio[i]=lastKRatio;
277  }
278  }
279  }
280  // Now one can use tabeles to calculate the value
281  if(m_s<sma) // Use linear table
282  {
283  G4int n=static_cast<int>(m_s/ds); // Low edge number of the bin
284  G4double d=m_s-n*ds; // Linear shift
285  G4double v=lastTRatio[n]; // Base
286  lastRRatio=v+d*(lastTRatio[n+1]-v)/ds; // Result
287  }
288  else // Use log table
289  {
290  G4double ls=std::log(m_s)-lsi; // ln(s)-l_min
291  G4int n=static_cast<int>(ls/dls); // Low edge number of the bin
292  G4double d=ls-n*dls; // Log shift
293  G4double v=lastLRatio[n]; // Base
294  lastRRatio=v+d*(lastLRatio[n+1]-v)/dls; // Result
295  }
296  if(lastRRatio<0.) lastRRatio=0.;
297  if(lastRRatio>1.) lastRRatio=1.;
298  return lastRRatio;
299 } // End of CalcQF2IN_Ratio
300 
301 // Calculatio QasiFree/Inelastic Ratio as a function of total hN cross-section and A
303 {
304  G4double s2=m_s*m_s;
305  G4double s4=s2*s2;
306  G4double ss=std::sqrt(std::sqrt(m_s));
307  G4double P=7.48e-5*s2/(1.+8.77e12/s4/s4/s2);
308  G4double E=.2644+.016/(1.+std::exp((29.54-m_s)/2.49));
309  G4double F=ss*.1526*std::exp(-s2*ss*.0000859);
310  return C*std::exp(-E*std::pow(G4double(A-1.),F))/std::pow(G4double(A),P);
311 } // End of CalcQF2IN_Ratio
312 
313 // Calculatio pair(hN_el,hN_tot) (mb): p in GeV/c, index(PDG,F) (see FetchElTot)
314 std::pair<G4double,G4double> G4QuasiElRatios::CalcElTot(G4double p, G4int I)
315 {
316  // ---------> Each parameter set can have not more than nPoints=128 parameters
317 
318  G4double El=0.; // prototype of the elastic hN cross-section
319  G4double To=0.; // prototype of the total hN cross-section
320  if(p<=0.)
321  {
322  G4cout<<"-Warning-G4QuasiElRatios::CalcElTot: p="<<p<<" is zero or negative"<<G4endl;
323  return std::make_pair(El,To);
324  }
325  if (!I) // pp/nn
326  {
327  if(p<pmi)
328  {
329  G4double p2=p*p;
330  El=1./(.00012+p2*.2);
331  To=El;
332  }
333  else if(p>pma)
334  {
335  G4double lp=std::log(p)-lmi;
336  G4double lp2=lp*lp;
337  El=pbe*lp2+6.72;
338  To=pbt*lp2+38.2;
339  }
340  else
341  {
342  G4double p2=p*p;
343  G4double LE=1./(.00012+p2*.2);
344  G4double lp=std::log(p)-lmi;
345  G4double lp2=lp*lp;
346  G4double rp2=1./p2;
347  El=LE+(pbe*lp2+6.72+32.6/p)/(1.+rp2/p);
348  To=LE+(pbt*lp2+38.2+52.7*rp2)/(1.+2.72*rp2*rp2);
349  }
350  }
351  else if(I==1) // np/pn
352  {
353  if(p<pmi)
354  {
355  G4double p2=p*p;
356  El=1./(.00012+p2*(.051+.1*p2));
357  To=El;
358  }
359  else if(p>pma)
360  {
361  G4double lp=std::log(p)-lmi;
362  G4double lp2=lp*lp;
363  El=pbe*lp2+6.72;
364  To=pbt*lp2+38.2;
365  }
366  else
367  {
368  G4double p2=p*p;
369  G4double LE=1./(.00012+p2*(.051+.1*p2));
370  G4double lp=std::log(p)-lmi;
371  G4double lp2=lp*lp;
372  G4double rp2=1./p2;
373  El=LE+(pbe*lp2+6.72+30./p)/(1.+.49*rp2/p);
374  To=LE+(pbt*lp2+38.2)/(1.+.54*rp2*rp2);
375  }
376  }
377  else if(I==2) // pimp/pipn
378  {
379  G4double lp=std::log(p);
380  if(p<pmi)
381  {
382  G4double lr=lp+1.27;
383  El=1.53/(lr*lr+.0676);
384  To=El*3;
385  }
386  else if(p>pma)
387  {
388  G4double ld=lp-lmi;
389  G4double ld2=ld*ld;
390  G4double sp=std::sqrt(p);
391  El=pbe*ld2+2.4+7./sp;
392  To=pbt*ld2+22.3+12./sp;
393  }
394  else
395  {
396  G4double lr=lp+1.27; // p1
397  G4double LE=1.53/(lr*lr+.0676); // p2, p3
398  G4double ld=lp-lmi; // p4 (lmi=3.5)
399  G4double ld2=ld*ld;
400  G4double p2=p*p;
401  G4double p4=p2*p2;
402  G4double sp=std::sqrt(p);
403  G4double lm=lp+.36; // p5
404  G4double md=lm*lm+.04; // p6
405  G4double lh=lp-.017; // p7
406  G4double hd=lh*lh+.0025; // p8
407  El=LE+(pbe*ld2+2.4+7./sp)/(1.+.7/p4)+.6/md+.05/hd;//p9(pbe=.0557),p10,p11,p12,p13,p14
408  To=LE*3+(pbt*ld2+22.3+12./sp)/(1.+.4/p4)+1./md+.06/hd;
409  }
410  }
411  else if(I==3) // pipp/pimn
412  {
413  G4double lp=std::log(p);
414  if(p<pmi)
415  {
416  G4double lr=lp+1.27;
417  G4double lr2=lr*lr;
418  El=13./(lr2+lr2*lr2+.0676);
419  To=El;
420  }
421  else if(p>pma)
422  {
423  G4double ld=lp-lmi;
424  G4double ld2=ld*ld;
425  G4double sp=std::sqrt(p);
426  El=pbe*ld2+2.4+6./sp;
427  To=pbt*ld2+22.3+5./sp;
428  }
429  else
430  {
431  G4double lr=lp+1.27; // p1
432  G4double lr2=lr*lr;
433  G4double LE=13./(lr2+lr2*lr2+.0676); // p2, p3
434  G4double ld=lp-lmi; // p4 (lmi=3.5)
435  G4double ld2=ld*ld;
436  G4double p2=p*p;
437  G4double p4=p2*p2;
438  G4double sp=std::sqrt(p);
439  G4double lm=lp-.32; // p5
440  G4double md=lm*lm+.0576; // p6
441  El=LE+(pbe*ld2+2.4+6./sp)/(1.+3./p4)+.7/md; // p7(pbe=.0557), p8, p9, p10, p11
442  To=LE+(pbt*ld2+22.3+5./sp)/(1.+1./p4)+.8/md;
443  }
444  }
445  else if(I==4) // Kmp/Kmn/K0p/K0n
446  {
447 
448  if(p<pmi)
449  {
450  G4double psp=p*std::sqrt(p);
451  El=5.2/psp;
452  To=14./psp;
453  }
454  else if(p>pma)
455  {
456  G4double ld=std::log(p)-lmi;
457  G4double ld2=ld*ld;
458  El=pbe*ld2+2.23;
459  To=pbt*ld2+19.5;
460  }
461  else
462  {
463  G4double ld=std::log(p)-lmi;
464  G4double ld2=ld*ld;
465  G4double sp=std::sqrt(p);
466  G4double psp=p*sp;
467  G4double p2=p*p;
468  G4double p4=p2*p2;
469  G4double lm=p-.39;
470  G4double md=lm*lm+.000156;
471  G4double lh=p-1.;
472  G4double hd=lh*lh+.0156;
473  El=5.2/psp+(pbe*ld2+2.23)/(1.-.7/sp+.075/p4)+.004/md+.15/hd;
474  To=14./psp+(pbt*ld2+19.5)/(1.-.21/sp+.52/p4)+.006/md+.30/hd;
475  }
476  }
477  else if(I==5) // Kpp/Kpn/aKp/aKn
478  {
479  if(p<pmi)
480  {
481  G4double lr=p-.38;
482  G4double lm=p-1.;
483  G4double md=lm*lm+.372;
484  El=.7/(lr*lr+.0676)+2./md;
485  To=El+.6/md;
486  }
487  else if(p>pma)
488  {
489  G4double ld=std::log(p)-lmi;
490  G4double ld2=ld*ld;
491  El=pbe*ld2+2.23;
492  To=pbt*ld2+19.5;
493  }
494  else
495  {
496  G4double ld=std::log(p)-lmi;
497  G4double ld2=ld*ld;
498  G4double lr=p-.38;
499  G4double LE=.7/(lr*lr+.0676);
500  G4double sp=std::sqrt(p);
501  G4double p2=p*p;
502  G4double p4=p2*p2;
503  G4double lm=p-1.;
504  G4double md=lm*lm+.372;
505  El=LE+(pbe*ld2+2.23)/(1.-.7/sp+.1/p4)+2./md;
506  To=LE+(pbt*ld2+19.5)/(1.+.46/sp+1.6/p4)+2.6/md;
507  }
508  }
509  else if(I==6) // hyperon-N
510  {
511  if(p<pmi)
512  {
513  G4double p2=p*p;
514  El=1./(.002+p2*(.12+p2));
515  To=El;
516  }
517  else if(p>pma)
518  {
519  G4double lp=std::log(p)-lmi;
520  G4double lp2=lp*lp;
521  G4double sp=std::sqrt(p);
522  El=(pbe*lp2+6.72)/(1.+2./sp);
523  To=(pbt*lp2+38.2+900./sp)/(1.+27./sp);
524  }
525  else
526  {
527  G4double p2=p*p;
528  G4double LE=1./(.002+p2*(.12+p2));
529  G4double lp=std::log(p)-lmi;
530  G4double lp2=lp*lp;
531  G4double p4=p2*p2;
532  G4double sp=std::sqrt(p);
533  El=LE+(pbe*lp2+6.72+99./p2)/(1.+2./sp+2./p4);
534  To=LE+(pbt*lp2+38.2+900./sp)/(1.+27./sp+3./p4);
535  }
536  }
537  else if(I==7) // antibaryon-N
538  {
539  if(p>pma)
540  {
541  G4double lp=std::log(p)-lmi;
542  G4double lp2=lp*lp;
543  El=pbe*lp2+6.72;
544  To=pbt*lp2+38.2;
545  }
546  else
547  {
548  G4double ye=std::pow(p,1.25);
549  G4double yt=std::pow(p,.35);
550  G4double lp=std::log(p)-lmi;
551  G4double lp2=lp*lp;
552  El=80./(ye+1.)+pbe*lp2+6.72;
553  To=(80./yt+.3)/yt+pbt*lp2+38.2;
554  }
555  }
556  else
557  {
558  G4cout<<"*Error*G4QuasiElRatios::CalcElTot:ind="<<I<<" is not defined (0-7)"<<G4endl;
559  G4Exception("G4QuasiElRatios::CalcElTot:","23",FatalException,"QEcrash");
560  }
561  if(El>To) El=To;
562  return std::make_pair(El,To);
563 } // End of CalcElTot
564 
565 // For hadron PDG with momentum Mom (GeV/c) on N (p/n) calculate <sig_el,sig_tot> pair (mb)
566 std::pair<G4double,G4double> G4QuasiElRatios::GetElTotXS(G4double p, G4int PDG, G4bool F)
567 {
568  G4int ind=0; // Prototype of the reaction index
569  G4bool kfl=true; // Flag of K0/aK0 oscillation
570  G4bool kf=false;
571  if(PDG==130||PDG==310)
572  {
573  kf=true;
574  if(G4UniformRand()>.5) kfl=false;
575  }
576  if ( (PDG == 2212 && F) || (PDG == 2112 && !F) ) ind=0; // pp/nn
577  else if ( (PDG == 2112 && F) || (PDG == 2212 && !F) ) ind=1; // np/pn
578  else if ( (PDG == -211 && F) || (PDG == 211 && !F) ) ind=2; // pimp/pipn
579  else if ( (PDG == 211 && F) || (PDG == -211 && !F) ) ind=3; // pipp/pimn
580  else if ( PDG == -321 || PDG == -311 || (kf && !kfl) ) ind=4; // KmN/K0N
581  else if ( PDG == 321 || PDG == 311 || (kf && kfl) ) ind=5; // KpN/aK0N
582  else if ( PDG > 3000 && PDG < 3335) ind=6; // @@ for all hyperons - take Lambda
583  else if ( PDG > -3335 && PDG < -2000) ind=7; // @@ for all anti-baryons (anti-p/anti-n)
584  else {
585  G4cout<<"*Error*G4QuasiElRatios::CalcElTotXS: PDG="<<PDG
586  <<", while it is defined only for p,n,hyperons,anti-baryons,pi,K/antiK"<<G4endl;
587  G4Exception("G4QuasiElRatio::CalcElTotXS:","22",FatalException,"QEcrash");
588  }
589  return CalcElTot(p,ind);
590 }
591 
592 // Calculatio pair(hN_el,hN_tot)(mb): p in GeV/c, F=true -> N=proton, F=false -> N=neutron
593 std::pair<G4double,G4double> G4QuasiElRatios::FetchElTot(G4double p, G4int PDG, G4bool F)
594 {
595  // LogTable is created only if necessary. The ratio R(s>8100 mb) = 0 for any nuclei
596  G4int nDB=vItot.size(); // A number of hadrons already initialized in AMDB
597  if(nDB && lastHtot==PDG && lastFtot==F && p>0. && p==lastPtot) return lastRtot;// VI don't use toler.
598  // if(nDB && lastH==PDG && lastF==F && p>0. && std::fabs(p-lastP)/p<toler) return lastR;
599  lastHtot=PDG;
600  lastFtot=F;
601  G4int ind=-1; // Prototipe of the index of the PDG/F combination
602  // i=0: pp(nn), i=1: np(pn), i=2: pimp(pipn), i=3: pipp(pimn), i=4: Kmp(Kmn,K0n,K0p),
603  // i=5: Kpp(Kpn,aK0n,aK0p), i=6: Hp(Hn), i=7: app(apn,ann,anp)
604  G4bool kfl=true; // Flag of K0/aK0 oscillation
605  G4bool kf=false;
606  if(PDG==130||PDG==310)
607  {
608  kf=true;
609  if(G4UniformRand()>.5) kfl=false;
610  }
611  if ( (PDG == 2212 && F) || (PDG == 2112 && !F) ) ind=0; // pp/nn
612  else if ( (PDG == 2112 && F) || (PDG == 2212 && !F) ) ind=1; // np/pn
613  else if ( (PDG == -211 && F) || (PDG == 211 && !F) ) ind=2; // pimp/pipn
614  else if ( (PDG == 211 && F) || (PDG == -211 && !F) ) ind=3; // pipp/pimn
615  else if ( PDG == -321 || PDG == -311 || (kf && !kfl) ) ind=4; // KmN/K0N
616  else if ( PDG == 321 || PDG == 311 || (kf && kfl) ) ind=5; // KpN/aK0N
617  else if ( PDG > 3000 && PDG < 3335) ind=6; // @@ for all hyperons - take Lambda
618  else if ( PDG > -3335 && PDG < -2000) ind=7; // @@ for all anti-baryons (anti-p/anti-n)
619  else {
620  G4cout<<"*Error*G4QuasiElRatios::FetchElTot: PDG="<<PDG
621  <<", while it is defined only for p,n,hyperons,anti-baryons,pi,K/antiK"<<G4endl;
622  G4Exception("G4QuasiELRatio::FetchElTot:","22",FatalException,"QECrash");
623  }
624  if(nDB && lastItot==ind && p>0. && p==lastPtot) return lastRtot; // VI do not use toler
625  // if(nDB && lastI==ind && p>0. && std::fabs(p-lastP)/p<toler) return lastR;
626  if(p<=mip || p>=map) return CalcElTot(p,ind); // @@ Slow calculation ! (Warning?)
627  G4bool found=false;
628  G4int i=-1;
629  if(nDB) for (i=0; i<nDB; i++) if(ind==vItot[i]) // Sirch for this index in AMDB
630  {
631  found=true; // The index is found
632  break;
633  }
634  G4double lp=std::log(p);
635  if(!nDB || !found) // Create new line in the AMDB
636  {
637  lastXtot = new std::pair<G4double,G4double>[mlp]; // Create logarithmic Table for ElTot
638  lastItot = ind; // Remember the initialized inex
639  lastKtot = static_cast<int>((lp-lpi)/dlp)+1; // MaxBin to be initialized in LogTaB
640  if(lastKtot>nlp)
641  {
642  lastKtot=nlp;
643  lastMtot=lpa-lpi;
644  }
645  else lastMtot = lastKtot*dlp; // Calculate max initialized ln(p)-lpi for LogTab
646  G4double pv=mip;
647  for(G4int j=0; j<=lastKtot; j++) // Calculate LogTab values
648  {
649  lastXtot[j]=CalcElTot(pv,ind);
650  if(j!=lastKtot) pv*=edlp;
651  }
652  i++; // Make a new record to AMDB and position on it
653  vItot.push_back(lastItot);
654  vMtot.push_back(lastMtot);
655  vKtot.push_back(lastKtot);
656  vX->push_back(lastXtot);
657  }
658  else // The A value was found in AMDB
659  {
660  lastItot=vItot[i];
661  lastMtot=vMtot[i];
662  lastKtot=vKtot[i];
663  lastXtot=(*vX)[i];
664  G4int nextK=lastKtot+1;
665  G4double lpM=lastMtot+lpi;
666  if(lp>lpM && lastKtot<nlp) // LogTab must be updated
667  {
668  lastKtot = static_cast<int>((lp-lpi)/dlp)+1; // MaxBin to be initialized in LogTab
669  if(lastKtot>nlp)
670  {
671  lastKtot=nlp;
672  lastMtot=lpa-lpi;
673  }
674  else lastMtot = lastKtot*dlp; // Calculate max initialized ln(p)-lpi for LogTab
675  G4double pv=std::exp(lpM); // momentum of the last calculated beam
676  for(G4int j=nextK; j<=lastKtot; j++)// Calculate LogTab values
677  {
678  pv*=edlp;
679  lastXtot[j]=CalcElTot(pv,ind);
680  }
681  } // End of LogTab update
682  if(lastKtot>=nextK) // The AMDB was apdated
683  {
684  vMtot[i]=lastMtot;
685  vKtot[i]=lastKtot;
686  }
687  }
688  // Now one can use tabeles to calculate the value
689  G4double dlpp=lp-lpi; // Shifted log(p) value
690  G4int n=static_cast<int>(dlpp/dlp); // Low edge number of the bin
691  G4double d=dlpp-n*dlp; // Log shift
692  G4double e=lastXtot[n].first; // E-Base
693  lastRtot.first=e+d*(lastXtot[n+1].first-e)/dlp; // E-Result
694  if(lastRtot.first<0.) lastRtot.first = 0.;
695  G4double t=lastXtot[n].second; // T-Base
696  lastRtot.second=t+d*(lastXtot[n+1].second-t)/dlp; // T-Result
697  if(lastRtot.second<0.) lastRtot.second= 0.;
698  if(lastRtot.first>lastRtot.second) lastRtot.first = lastRtot.second;
699  return lastRtot;
700 } // End of FetchElTot
701 
702 // (Mean Elastic and Mean Total) Cross-Sections (mb) for PDG+(Z,N) at P=p[GeV/c]
703 std::pair<G4double,G4double> G4QuasiElRatios::GetElTot(G4double pIU, G4int hPDG,
704  G4int Z, G4int N)
705 {
706  G4double pGeV=pIU/gigaelectronvolt;
707  if(Z<1 && N<1)
708  {
709  G4cout<<"-Warning-G4QuasiElRatio::GetElTot:Z="<<Z<<",N="<<N<<", return zero"<<G4endl;
710  return std::make_pair(0.,0.);
711  }
712  std::pair<G4double,G4double> hp=FetchElTot(pGeV, hPDG, true);
713  std::pair<G4double,G4double> hn=FetchElTot(pGeV, hPDG, false);
714  G4double A=(Z+N)/millibarn; // To make the result in independent units(IU)
715  return std::make_pair((Z*hp.first+N*hn.first)/A,(Z*hp.second+N*hn.second)/A);
716 } // End of GetElTot
717 
718 // (Mean Elastic and Mean Total) Cross-Sections (mb) for PDG+(Z,N) at P=p[GeV/c]
719 std::pair<G4double,G4double> G4QuasiElRatios::GetChExFactor(G4double pIU, G4int hPDG,
720  G4int Z, G4int N)
721 {
722  G4double pGeV=pIU/gigaelectronvolt;
723  G4double resP=0.;
724  G4double resN=0.;
725  if(Z<1 && N<1)
726  {
727  G4cout<<"-Warning-G4QuasiElRatio::GetChExF:Z="<<Z<<",N="<<N<<", return zero"<<G4endl;
728  return std::make_pair(resP,resN);
729  }
730  G4double A=Z+N;
731  G4double pf=0.; // Possibility to interact with a proton
732  G4double nf=0.; // Possibility to interact with a neutron
733  if (hPDG==-211||hPDG==-321||hPDG==3112||hPDG==3212||hPDG==3312) pf=Z/(A+N);
734  else if(hPDG==211||hPDG==321||hPDG==3222||hPDG==3212||hPDG==3322) nf=N/(A+Z);
735  else if(hPDG==-311||hPDG==311||hPDG==130||hPDG==310)
736  {
737  G4double dA=A+A;
738  pf=Z/(dA+N+N);
739  nf=N/(dA+Z+Z);
740  }
741  G4double mult=1.; // Factor of increasing multiplicity ( ? @@)
742  if(pGeV>.5)
743  {
744  mult=1./(1.+std::log(pGeV+pGeV))/pGeV;
745  if(mult>1.) mult=1.;
746  }
747  if(pf)
748  {
749  std::pair<G4double,G4double> hp=FetchElTot(pGeV, hPDG, true);
750  resP=pf*(hp.second/hp.first-1.)*mult;
751  }
752  if(nf)
753  {
754  std::pair<G4double,G4double> hn=FetchElTot(pGeV, hPDG, false);
755  resN=nf*(hn.second/hn.first-1.)*mult;
756  }
757  return std::make_pair(resP,resN);
758 } // End of GetChExFactor
759 
760 // scatter (pPDG,p4M) on a virtual nucleon (NPDG,N4M), result: final pair(newN4M,newp4M)
761 // if(newN4M.e()==0.) - below threshold, XS=0, no scattering of the progectile happened
762 std::pair<G4LorentzVector,G4LorentzVector> G4QuasiElRatios::Scatter(G4int NPDG,
763  G4LorentzVector N4M, G4int pPDG, G4LorentzVector p4M)
764 {
765  static const G4double mNeut= G4Neutron::Neutron()->GetPDGMass();
766  static const G4double mProt= G4Proton::Proton()->GetPDGMass();
767  static const G4double mDeut= G4Deuteron::Deuteron()->GetPDGMass();
768  static const G4double mTrit= G4Triton::Triton()->GetPDGMass();
769  static const G4double mHel3= G4He3::He3()->GetPDGMass();
770  static const G4double mAlph= G4Alpha::Alpha()->GetPDGMass();
771 
772  G4LorentzVector pr4M=p4M/megaelectronvolt; // Convert 4-momenta in MeV (keep p4M)
773  N4M/=megaelectronvolt;
774  G4LorentzVector tot4M=N4M+p4M;
775  G4double mT=mNeut;
776  G4int Z=0;
777  G4int N=1;
778  if(NPDG==2212||NPDG==90001000)
779  {
780  mT=mProt;
781  Z=1;
782  N=0;
783  }
784  else if(NPDG==90001001)
785  {
786  mT=mDeut;
787  Z=1;
788  N=1;
789  }
790  else if(NPDG==90002001)
791  {
792  mT=mHel3;
793  Z=2;
794  N=1;
795  }
796  else if(NPDG==90001002)
797  {
798  mT=mTrit;
799  Z=1;
800  N=2;
801  }
802  else if(NPDG==90002002)
803  {
804  mT=mAlph;
805  Z=2;
806  N=2;
807  }
808  else if(NPDG!=2112&&NPDG!=90000001)
809  {
810  G4cout<<"Error:G4QuasiElRatios::Scatter:NPDG="<<NPDG<<" is not 2212 or 2112"<<G4endl;
811  G4Exception("G4QuasiElRatios::Scatter:","21",FatalException,"QEcomplain");
812  //return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M);// Use this if not exception
813  }
814  G4double mT2=mT*mT;
815  G4double mP2=pr4M.m2();
816  G4double E=(tot4M.m2()-mT2-mP2)/(mT+mT);
817  G4double E2=E*E;
818  if(E<0. || E2<mP2)
819  {
820  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
821  }
822  G4double P=std::sqrt(E2-mP2); // Momentum in pseudo laboratory system
823  // @@ Temporary NN t-dependence for all hadrons
824  if(pPDG>3400 || pPDG<-3400) G4cout<<"-Warning-G4QE::Scatter: pPDG="<<pPDG<<G4endl;
825  G4int PDG=2212; // *TMP* instead of pPDG
826  if(pPDG==2112||pPDG==-211||pPDG==-321) PDG=2112; // *TMP* instead of pPDG
827  if(!Z && N==1) // Change for Quasi-Elastic on neutron
828  {
829  Z=1;
830  N=0;
831  if (PDG==2212) PDG=2112;
832  else if(PDG==2112) PDG=2212;
833  }
834  G4double xSec=0.; // Prototype of Recalculated Cross Section *TMP*
835  if(PDG==2212) xSec=PCSmanager->GetChipsCrossSection(P, Z, N, PDG); // P CrossSect *TMP*
836  else xSec=NCSmanager->GetChipsCrossSection(P, Z, N, PDG); // N CrossSect *TMP*
837  // @@ check a possibility to separate p, n, or alpha (!)
838  if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
839  {
840  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); //Do Nothing Action
841  }
842  G4double mint=0.; // Prototype of functional rand -t (MeV^2) *TMP*
843  if(PDG==2212) mint=PCSmanager->GetExchangeT(Z,N,PDG);// P functional rand -t(MeV^2) *TMP*
844  else mint=NCSmanager->GetExchangeT(Z,N,PDG);// N functional rand -t(MeV^2) *TMP*
845  G4double maxt=0.; // Prototype of max possible -t
846  if(PDG==2212) maxt=PCSmanager->GetHMaxT(); // max possible -t
847  else maxt=NCSmanager->GetHMaxT(); // max possible -t
848  G4double cost=1.-(mint+mint)/maxt; // cos(theta) in CMS
849  if(cost>1. || cost<-1. || !(cost>-1. || cost<=1.))
850  {
851  if (cost>1.) cost=1.;
852  else if(cost<-1.) cost=-1.;
853  else
854  {
855  G4double tm=0.;
856  if(PDG==2212) tm=PCSmanager->GetHMaxT();
857  else tm=NCSmanager->GetHMaxT();
858  G4cerr<<"G4QuasiFreeRatio::Scat:*NAN* cost="<<cost<<",-t="<<mint<<",tm="<<tm<<G4endl;
859  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
860  }
861  }
862  G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,mT); // 4mom of the recoil nucleon
863  G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-mT)*.01);
864  if(!RelDecayIn2(tot4M, pr4M, reco4M, dir4M, cost, cost))
865  {
866  G4cerr<<"G4QFR::Scat:t="<<tot4M<<tot4M.m()<<",mT="<<mT<<",mP="<<std::sqrt(mP2)<<G4endl;
867  //G4Exception("G4QFR::Scat:","009",FatalException,"Decay of ElasticComp");
868  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
869  }
870  return std::make_pair(reco4M*megaelectronvolt,pr4M*megaelectronvolt); // Result
871 } // End of Scatter
872 
873 // scatter (pPDG,p4M) on a virtual nucleon (NPDG,N4M), result: final pair(newN4M,newp4M)
874 // if(newN4M.e()==0.) - below threshold, XS=0, no scattering of the progectile happened
875 // User should himself change the charge (PDG) (e.g. pn->np, pi+n->pi0p, pi-p->pi0n etc.)
876 std::pair<G4LorentzVector,G4LorentzVector> G4QuasiElRatios::ChExer(G4int NPDG,
877  G4LorentzVector N4M, G4int pPDG, G4LorentzVector p4M)
878 {
879  static const G4double mNeut= G4Neutron::Neutron()->GetPDGMass();
880  static const G4double mProt= G4Proton::Proton()->GetPDGMass();
881  G4LorentzVector pr4M=p4M/megaelectronvolt; // Convert 4-momenta in MeV(keep p4M)
882  N4M/=megaelectronvolt;
883  G4LorentzVector tot4M=N4M+p4M;
884  G4int Z=0;
885  G4int N=1;
886  G4int sPDG=0; // PDG code of the scattered hadron
887  G4double mS=0.; // proto of mass of scattered hadron
888  G4double mT=mProt; // mass of the recoil nucleon
889  if(NPDG==2212)
890  {
891  mT=mNeut;
892  Z=1;
893  N=0;
894  if(pPDG==-211) sPDG=111; // pi+ -> pi0
895  else if(pPDG==-321)
896  {
897  sPDG=310; // K+ -> K0S
898  if(G4UniformRand()>.5) sPDG=130; // K+ -> K0L
899  }
900  else if(pPDG==-311||pPDG==311||pPDG==130||pPDG==310) sPDG=321; // K0 -> K+ (?)
901  else if(pPDG==3112) sPDG=3212; // Sigma- -> Sigma0
902  else if(pPDG==3212) sPDG=3222; // Sigma0 -> Sigma+
903  else if(pPDG==3312) sPDG=3322; // Xi- -> Xi0
904  }
905  else if(NPDG==2112) // Default
906  {
907  if(pPDG==211) sPDG=111; // pi+ -> pi0
908  else if(pPDG==321)
909  {
910  sPDG=310; // K+ -> K0S
911  if(G4UniformRand()>.5) sPDG=130; // K+ -> K0L
912  }
913  else if(pPDG==-311||pPDG==311||pPDG==130||pPDG==310) sPDG=-321; // K0 -> K- (?)
914  else if(pPDG==3222) sPDG=3212; // Sigma+ -> Sigma0
915  else if(pPDG==3212) sPDG=3112; // Sigma0 -> Sigma-
916  else if(pPDG==3322) sPDG=3312; // Xi0 -> Xi-
917  }
918  else
919  {
920  G4cout<<"Error:G4QuasiElRatios::ChExer: NPDG="<<NPDG<<" is not 2212 or 2112"<<G4endl;
921  G4Exception("G4QuasiElRatios::ChExer:","21",FatalException,"QE complain");
922  //return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M);// Use this if not exception
923  }
924  if(sPDG) mS=mNeut;
925  else
926  {
927  G4cout<<"Error:G4QuasiElRatios::ChExer: BAD pPDG="<<pPDG<<", NPDG="<<NPDG<<G4endl;
928  G4Exception("G4QuasiElRatios::ChExer:","21",FatalException,"QE complain");
929  //return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M);// Use this if not exception
930  }
931  G4double mT2=mT*mT;
932  G4double mS2=mS*mS;
933  G4double E=(tot4M.m2()-mT2-mS2)/(mT+mT);
934  G4double E2=E*E;
935  if(E<0. || E2<mS2)
936  {
937  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
938  }
939  G4double P=std::sqrt(E2-mS2); // Momentum in pseudo laboratory system
940  // @@ Temporary NN t-dependence for all hadrons
941  G4int PDG=2212; // *TMP* instead of pPDG
942  if(pPDG==2112||pPDG==-211||pPDG==-321) PDG=2112; // *TMP* instead of pPDG
943  if(!Z && N==1) // Change for Quasi-Elastic on neutron
944  {
945  Z=1;
946  N=0;
947  if (PDG==2212) PDG=2112;
948  else if(PDG==2112) PDG=2212;
949  }
950  G4double xSec=0.; // Prototype of Recalculated Cross Section *TMP*
951  if(PDG==2212) xSec=PCSmanager->GetChipsCrossSection(P, Z, N, PDG); // P CrossSect *TMP*
952  else xSec=NCSmanager->GetChipsCrossSection(P, Z, N, PDG); // N CrossSect *TMP*
953  // @@ check a possibility to separate p, n, or alpha (!)
954  if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
955  {
956  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); //Do Nothing Action
957  }
958  G4double mint=0.; // Prototype of functional rand -t (MeV^2) *TMP*
959  if(PDG==2212) mint=PCSmanager->GetExchangeT(Z,N,PDG);// P functional rand -t(MeV^2) *TMP*
960  else mint=NCSmanager->GetExchangeT(Z,N,PDG);// N functional rand -t(MeV^2) *TMP*
961  G4double maxt=0.; // Prototype of max possible -t
962  if(PDG==2212) maxt=PCSmanager->GetHMaxT(); // max possible -t
963  else maxt=NCSmanager->GetHMaxT(); // max possible -t
964  G4double cost=1.-mint/maxt; // cos(theta) in CMS
965  if(cost>1. || cost<-1. || !(cost>-1. || cost<=1.))
966  {
967  if (cost>1.) cost=1.;
968  else if(cost<-1.) cost=-1.;
969  else
970  {
971  G4cerr<<"G4QuasiFreeRatio::ChExer:*NAN* c="<<cost<<",t="<<mint<<",tm="<<maxt<<G4endl;
972  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
973  }
974  }
975  G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,mT); // 4mom of the recoil nucleon
976  pr4M=G4LorentzVector(0.,0.,0.,mS); // 4mom of the scattered hadron
977  G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-mT)*.01);
978  if(!RelDecayIn2(tot4M, pr4M, reco4M, dir4M, cost, cost))
979  {
980  G4cerr<<"G4QFR::ChEx:t="<<tot4M<<tot4M.m()<<",mT="<<mT<<",mP="<<mS<<G4endl;
981  //G4Exception("G4QFR::ChExer:","009",FatalException,"Decay of ElasticComp");
982  return std::make_pair(G4LorentzVector(0.,0.,0.,0.),p4M); // Do Nothing Action
983  }
984  return std::make_pair(reco4M*megaelectronvolt,pr4M*megaelectronvolt); // Result
985 } // End of ChExer
986 
987 // Calculate ChEx/El ratio (p is in independent units, (Z,N) is target, pPDG is projectile)
989 {
990 
991  p/=MeV; // Converted from independent units
992  G4double A=Z+N;
993  if(A<1.5) return 0.;
994  G4double Cex=0.;
995  if (pPDG==2212) Cex=N/(A+Z);
996  else if(pPDG==2112) Cex=Z/(A+N);
997  else G4cout<<"*Warning*G4CohChrgExchange::ChExElCoef: wrong PDG="<<pPDG<<G4endl;
998  Cex*=Cex; // Coherent processes squares the amplitude
999  // @@ This is true only for nucleons: other projectiles must be treated differently
1000  G4double sp=std::sqrt(p);
1001  G4double p2=p*p;
1002  G4double p4=p2*p2;
1003  G4double dl1=std::log(p)-5.;
1004  G4double T=(6.75+.14*dl1*dl1+13./p)/(1.+.14/p4)+.6/(p4+.00013);
1005  G4double U=(6.25+8.33e-5/p4/p)*(p*sp+.34)/p2/p;
1006  G4double R=U/T;
1007  return Cex*R*R;
1008 }
1009 
1010 // Decay of Hadron In2Particles f&s, f is in respect to the direction of HadronMomentumDir
1012  G4LorentzVector& dir, G4double maxCost, G4double minCost)
1013 {
1014  G4double fM2 = f4Mom.m2();
1015  G4double fM = std::sqrt(fM2); // Mass of the 1st Hadron
1016  G4double sM2 = s4Mom.m2();
1017  G4double sM = std::sqrt(sM2); // Mass of the 2nd Hadron
1018  G4double iM2 = theMomentum.m2();
1019  G4double iM = std::sqrt(iM2); // Mass of the decaying hadron
1020  G4double vP = theMomentum.rho(); // Momentum of the decaying hadron
1021  G4double dE = theMomentum.e(); // Energy of the decaying hadron
1022  if(dE<vP)
1023  {
1024  G4cerr<<"***G4QHad::RelDecIn2: Tachionic 4-mom="<<theMomentum<<", E-p="<<dE-vP<<G4endl;
1025  G4double accuracy=.000001*vP;
1026  G4double emodif=std::fabs(dE-vP);
1027  //if(emodif<accuracy)
1028  //{
1029  G4cerr<<"G4QHadron::RelDecIn2: *Boost* E-p shift is corrected to "<<emodif<<G4endl;
1030  theMomentum.setE(vP+emodif+.01*accuracy);
1031  //}
1032  }
1033  G4ThreeVector ltb = theMomentum.boostVector();// Boost vector for backward Lorentz Trans.
1034  G4ThreeVector ltf = -ltb; // Boost vector for forward Lorentz Trans.
1035  G4LorentzVector cdir = dir; // A copy to make a transformation to CMS
1036  cdir.boost(ltf); // Direction transpormed to CMS of the Momentum
1037  G4ThreeVector vdir = cdir.vect(); // 3-Vector of the direction-particle
1038  G4ThreeVector vx(0.,0.,1.); // Ort in the direction of the reference particle
1039  G4ThreeVector vy(0.,1.,0.); // First ort orthogonal to the direction
1040  G4ThreeVector vz(1.,0.,0.); // Second ort orthoganal to the direction
1041  if(vdir.mag2() > 0.) // the refference particle isn't at rest in CMS
1042  {
1043  vx = vdir.unit(); // Ort in the direction of the reference particle
1044  G4ThreeVector vv= vx.orthogonal(); // Not normed orthogonal vector (!)
1045  vy = vv.unit(); // First ort orthogonal to the direction
1046  vz = vx.cross(vy); // Second ort orthoganal to the direction
1047  }
1048  if(maxCost> 1.) maxCost= 1.;
1049  if(minCost<-1.) minCost=-1.;
1050  if(maxCost<-1.) maxCost=-1.;
1051  if(minCost> 1.) minCost= 1.;
1052  if(minCost> maxCost) minCost=maxCost;
1053  if(std::fabs(iM-fM-sM)<.00000001)
1054  {
1055  G4double fR=fM/iM;
1056  G4double sR=sM/iM;
1057  f4Mom=fR*theMomentum;
1058  s4Mom=sR*theMomentum;
1059  return true;
1060  }
1061  else if (iM+.001<fM+sM || iM==0.)
1062  {//@@ Later on make a quark content check for the decay
1063  G4cerr<<"***G4QH::RelDecIn2: fM="<<fM<<"+sM="<<sM<<">iM="<<iM<<",d="<<iM-fM-sM<<G4endl;
1064  return false;
1065  }
1066  G4double d2 = iM2-fM2-sM2;
1067  G4double p2 = (d2*d2/4.-fM2*sM2)/iM2; // Decay momentum(^2) in CMS of Quasmon
1068  if(p2<0.)
1069  {
1070  p2=0.;
1071  }
1072  G4double p = std::sqrt(p2);
1073  G4double ct = maxCost;
1074  if(maxCost>minCost)
1075  {
1076  G4double dcost=maxCost-minCost;
1077  ct = minCost+dcost*G4UniformRand();
1078  }
1079  G4double phi= twopi*G4UniformRand(); // @@ Change 360.*deg to M_TWOPI (?)
1080  G4double ps=0.;
1081  if(std::fabs(ct)<1.) ps = p * std::sqrt(1.-ct*ct);
1082  else
1083  {
1084  if(ct>1.) ct=1.;
1085  if(ct<-1.) ct=-1.;
1086  }
1087  G4ThreeVector pVect=(ps*std::sin(phi))*vz+(ps*std::cos(phi))*vy+p*ct*vx;
1088 
1089  f4Mom.setVect(pVect);
1090  f4Mom.setE(std::sqrt(fM2+p2));
1091  s4Mom.setVect((-1)*pVect);
1092  s4Mom.setE(std::sqrt(sM2+p2));
1093 
1094  if(f4Mom.e()+.001<f4Mom.rho())G4cerr<<"*G4QH::RDIn2:*Boost* f4M="<<f4Mom<<",e-p="
1095  <<f4Mom.e()-f4Mom.rho()<<G4endl;
1096  f4Mom.boost(ltb); // Lor.Trans. of 1st hadron back to LS
1097  if(s4Mom.e()+.001<s4Mom.rho())G4cerr<<"*G4QH::RDIn2:*Boost* s4M="<<s4Mom<<",e-p="
1098  <<s4Mom.e()-s4Mom.rho()<<G4endl;
1099  s4Mom.boost(ltb); // Lor.Trans. of 2nd hadron back to LS
1100  return true;
1101 } // End of "RelDecayIn2"
1102 
1103 
1104 
1105 
1106 
1107 
G4VCrossSectionDataSet * GetCrossSectionDataSet(const G4String &name, G4bool warning=true)
std::pair< G4double, G4double > GetRatios(G4double pIU, G4int prPDG, G4int tgZ, G4int tgN)
std::vector< G4double > vMRatio
static const double MeV
Definition: G4SIunits.hh:193
static const double megaelectronvolt
Definition: G4SIunits.hh:187
CLHEP::Hep3Vector G4ThreeVector
virtual G4double GetChipsCrossSection(G4double momentum, G4int Z, G4int N, G4int pdg)
std::vector< G4double > vHRatio
std::vector< G4double * > * vT
G4ChipsProtonElasticXS * PCSmanager
std::vector< G4int > vKtot
std::pair< G4double, G4double > FetchElTot(G4double pGeV, G4int PDG, G4bool F)
std::vector< G4double > vMtot
int G4int
Definition: G4Types.hh:78
std::pair< G4double, G4double > GetElTot(G4double pIU, G4int hPDG, G4int Z, G4int N)
std::pair< G4LorentzVector, G4LorentzVector > Scatter(G4int NPDG, G4LorentzVector N4M, G4int pPDG, G4LorentzVector p4M)
std::pair< G4double, G4double > lastRtot
std::pair< G4double, G4double > GetChExFactor(G4double pIU, G4int pPDG, G4int Z, G4int N)
std::vector< G4int > vKRatio
G4double * lastLRatio
static const G4double dE
G4double * lastTRatio
#define G4UniformRand()
Definition: Randomize.hh:93
G4GLOB_DLL std::ostream G4cout
std::vector< std::pair< G4double, G4double > * > * vX
std::vector< G4double * > * vL
bool G4bool
Definition: G4Types.hh:79
G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG)
const G4double p2
static const char * Default_Name()
static G4CrossSectionDataSetRegistry * Instance()
static G4Triton * Triton()
Definition: G4Triton.cc:95
static G4Proton * Proton()
Definition: G4Proton.cc:93
G4double GetQF2IN_Ratio(G4double TotCS_mb, G4int A)
G4double CalcQF2IN_Ratio(G4double TCSmb, G4int A)
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
const G4int n
std::vector< G4int > vItot
static const G4double A[nN]
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
std::pair< G4double, G4double > * lastXtot
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::pair< G4LorentzVector, G4LorentzVector > ChExer(G4int NPDG, G4LorentzVector N4M, G4int pPDG, G4LorentzVector p4M)
G4double ChExElCoef(G4double p, G4int Z, G4int N, G4int pPDG)
Definition: Evaluator.cc:66
G4bool RelDecayIn2(G4LorentzVector &theMomentum, G4LorentzVector &f4Mom, G4LorentzVector &s4Mom, G4LorentzVector &dir, G4double maxCost=1., G4double minCost=-1.)
G4double GetPDGMass() const
std::pair< G4double, G4double > CalcElTot(G4double pGeV, G4int Index)
static const double gigaelectronvolt
Definition: G4SIunits.hh:188
static const double millibarn
Definition: G4SIunits.hh:96
static const char * Default_Name()
#define G4endl
Definition: G4ios.hh:61
std::vector< G4int > vARatio
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
std::pair< G4double, G4double > GetElTotXS(G4double Mom, G4int PDG, G4bool F)
double G4double
Definition: G4Types.hh:76
static const G4double d2
std::vector< G4int > vNRatio
static G4He3 * He3()
Definition: G4He3.cc:94
static const G4double pos
virtual G4double GetChipsCrossSection(G4double momentum, G4int Z, G4int N, G4int pdg)
G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG)
G4GLOB_DLL std::ostream G4cerr
G4ChipsNeutronElasticXS * NCSmanager
CLHEP::HepLorentzVector G4LorentzVector