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