51#include "FullModelReactionDynamics.hh"
52#include "G4Version.hh"
53#include "G4AntiProton.hh"
54#include "G4AntiNeutron.hh"
55#include "Randomize.hh"
57#if G4VERSION_NUMBER < 1100
58#include "G4HadReentrentException.hh"
60#include "G4HadronicException.hh"
104G4bool FullModelReactionDynamics::GenerateXandPt(
105 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
107 G4ReactionProduct &modifiedOriginal,
108 const G4HadProjectile *originalIncident,
109 G4ReactionProduct ¤tParticle,
110 G4ReactionProduct &targetParticle,
111 const G4Nucleus &targetNucleus,
112 G4bool &incidentHasChanged,
113 G4bool &targetHasChanged,
115 G4ReactionProduct &leadingStrangeParticle )
130 if(vecLen == 0)
return false;
132 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
135 G4ParticleDefinition *aProton = G4Proton::Proton();
136 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
137 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
138 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
139 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
140 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
141 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
142 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
146 G4bool veryForward =
false;
148 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/CLHEP::GeV;
149 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/CLHEP::GeV;
150 const G4double mOriginal = modifiedOriginal.GetMass()/CLHEP::GeV;
151 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/CLHEP::GeV;
152 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/CLHEP::GeV;
153 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
154 targetMass*targetMass +
155 2.0*targetMass*etOriginal );
156 G4double currentMass = currentParticle.GetMass()/CLHEP::GeV;
157 targetMass = targetParticle.GetMass()/CLHEP::GeV;
162 for( i=0;
i<vecLen; ++
i )
164 G4int itemp = G4int( G4UniformRand()*vecLen );
165 G4ReactionProduct pTemp = *
vec[itemp];
171 if( currentMass == 0.0 && targetMass == 0.0 )
174 G4double ek = currentParticle.GetKineticEnergy();
175 G4ThreeVector
m = currentParticle.GetMomentum();
176 currentParticle = *
vec[0];
177 targetParticle = *
vec[1];
178 for( i=0;
i<(vecLen-2); ++
i )*
vec[i] = *
vec[i+2];
179 G4ReactionProduct *temp =
vec[vecLen-1];
181 temp =
vec[vecLen-2];
184 currentMass = currentParticle.GetMass()/CLHEP::GeV;
185 targetMass = targetParticle.GetMass()/CLHEP::GeV;
186 incidentHasChanged =
true;
187 targetHasChanged =
true;
188 currentParticle.SetKineticEnergy( ek );
189 currentParticle.SetMomentum( m );
193 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
195 const G4double atomicNumber = targetNucleus.GetZ_asInt();
196 const G4double protonMass = aProton->GetPDGMass()/CLHEP::MeV;
197 if( (originalIncident->GetDefinition() == aKaonMinus ||
198 originalIncident->GetDefinition() == aKaonZeroL ||
199 originalIncident->GetDefinition() == aKaonZeroS ||
200 originalIncident->GetDefinition() == aKaonPlus) &&
201 G4UniformRand() >= 0.7 )
203 G4ReactionProduct temp = currentParticle;
204 currentParticle = targetParticle;
205 targetParticle = temp;
206 incidentHasChanged =
true;
207 targetHasChanged =
true;
208 currentMass = currentParticle.GetMass()/CLHEP::GeV;
209 targetMass = targetParticle.GetMass()/CLHEP::GeV;
211 const G4double afc = std::min( 0.75,
212 0.312+0.200*std::log(std::log(centerofmassEnergy*centerofmassEnergy))+
213 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 );
217 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass;
221 G4cout<<
"Free energy < 0!"<<G4endl;
222 G4cout<<
"E_CMS = "<<centerofmassEnergy<<
" GeV"<<G4endl;
223 G4cout<<
"m_curr = "<<currentMass<<
" GeV"<<G4endl;
224 G4cout<<
"m_orig = "<<mOriginal<<
" GeV"<<G4endl;
225 G4cout<<
"m_targ = "<<targetMass<<
" GeV"<<G4endl;
226 G4cout<<
"E_free = "<<freeEnergy<<
" GeV"<<G4endl;
229 G4double forwardEnergy = freeEnergy/2.;
230 G4int forwardCount = 1;
232 G4double backwardEnergy = freeEnergy/2.;
233 G4int backwardCount = 1;
236 if(currentParticle.GetSide()==-1)
238 forwardEnergy += currentMass;
240 backwardEnergy -= currentMass;
243 if(targetParticle.GetSide()!=-1)
245 backwardEnergy += targetMass;
247 forwardEnergy -= targetMass;
251 for( i=0;
i<vecLen; ++
i )
253 if(
vec[i]->GetSide() == -1 )
256 backwardEnergy -=
vec[
i]->GetMass()/CLHEP::GeV;
259 forwardEnergy -=
vec[
i]->GetMass()/CLHEP::GeV;
268 if( centerofmassEnergy < (2.0+G4UniformRand()) )
269 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0;
271 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount);
272 if( xtarg <= 0.0 )xtarg = 0.01;
273 G4int nuclearExcitationCount =
Poisson( xtarg );
274 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
275 G4int extraNucleonCount = 0;
276 if( nuclearExcitationCount > 0 )
278 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 };
279 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. };
280 G4int momentumBin = 0;
281 while( (momentumBin < 6) &&
282 (modifiedOriginal.GetTotalMomentum()/CLHEP::GeV > psup[momentumBin]) )
284 momentumBin = std::min( 5, momentumBin );
290 for( i=0;
i<nuclearExcitationCount; ++
i )
292 G4ReactionProduct * pVec =
new G4ReactionProduct();
293 if( G4UniformRand() < nucsup[momentumBin] )
295 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
296 pVec->SetDefinition( aProton );
298 pVec->SetDefinition( aNeutron );
301 backwardEnergy += pVec->GetMass()/CLHEP::GeV;
305 G4double ran = G4UniformRand();
307 pVec->SetDefinition( aPiPlus );
308 else if( ran < 0.6819 )
309 pVec->SetDefinition( aPiZero );
311 pVec->SetDefinition( aPiMinus );
314 pVec->SetNewlyAdded(
true );
315 vec.SetElement( vecLen++, pVec );
317 backwardEnergy -= pVec->GetMass()/CLHEP::GeV;
325 while( forwardEnergy <= 0.0 )
328 iskip = G4int(G4UniformRand()*forwardCount) + 1;
330 G4int forwardParticlesLeft = 0;
331 for( i=(vecLen-1);
i>=0; --
i )
333 if(
vec[i]->GetSide() == 1 &&
vec[i]->GetMayBeKilled())
335 forwardParticlesLeft = 1;
338 forwardEnergy +=
vec[
i]->GetMass()/CLHEP::GeV;
339 for( G4int j=i;
j<(vecLen-1);
j++ )*
vec[j] = *
vec[j+1];
341 G4ReactionProduct *temp =
vec[vecLen-1];
343 if( --vecLen == 0 )
return false;
349 if( forwardParticlesLeft == 0 )
351 forwardEnergy += currentParticle.GetMass()/CLHEP::GeV;
352 currentParticle.SetDefinitionAndUpdateE( targetParticle.GetDefinition() );
353 targetParticle.SetDefinitionAndUpdateE(
vec[0]->GetDefinition() );
356 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
357 G4ReactionProduct *temp =
vec[vecLen-1];
359 if( --vecLen == 0 )
return false;
364 while( backwardEnergy <= 0.0 )
367 iskip = G4int(G4UniformRand()*backwardCount) + 1;
369 G4int backwardParticlesLeft = 0;
370 for( i=(vecLen-1);
i>=0; --
i )
372 if(
vec[i]->GetSide() < 0 &&
vec[i]->GetMayBeKilled())
374 backwardParticlesLeft = 1;
377 if(
vec[i]->GetSide() == -2 )
380 backwardEnergy -=
vec[
i]->GetTotalEnergy()/CLHEP::GeV;
382 backwardEnergy +=
vec[
i]->GetTotalEnergy()/CLHEP::GeV;
383 for( G4int j=i;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
385 G4ReactionProduct *temp =
vec[vecLen-1];
387 if( --vecLen == 0 )
return false;
393 if( backwardParticlesLeft == 0 )
395 backwardEnergy += targetParticle.GetMass()/CLHEP::GeV;
396 targetParticle = *
vec[0];
398 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
399 G4ReactionProduct *temp =
vec[vecLen-1];
401 if( --vecLen == 0 )
return false;
410 G4ReactionProduct pseudoParticle[10];
411 for( i=0;
i<10; ++
i )pseudoParticle[i].SetZero();
413 pseudoParticle[0].SetMass( mOriginal*CLHEP::GeV );
414 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*CLHEP::GeV );
415 pseudoParticle[0].SetTotalEnergy(
416 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*CLHEP::GeV );
418 pseudoParticle[1].SetMass( protonMass*CLHEP::MeV );
419 pseudoParticle[1].SetTotalEnergy( protonMass*CLHEP::MeV );
421 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*CLHEP::MeV );
422 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*CLHEP::MeV );
424 pseudoParticle[8].SetMomentum( 1.0*CLHEP::GeV, 0.0, 0.0 );
426 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
427 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
429 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
430 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
437 G4double aspar,
pt,
et,
x, pp, pp1, rthnve, phinve, rmb, wgt;
438 G4int innerCounter, outerCounter;
439 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
441 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
447 G4double binl[20] = {0.,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.11,1.25,
448 1.43,1.67,2.0,2.5,3.33,5.00,10.00};
449 G4int backwardNucleonCount = 0;
450 G4double totalEnergy, kineticEnergy, vecMass;
452 for( i=(vecLen-1);
i>=0; --
i )
454 G4double
phi = G4UniformRand()*CLHEP::twopi;
455 if(
vec[i]->GetNewlyAdded() )
457 if(
vec[i]->GetSide() == -2 )
459 if( backwardNucleonCount < 18 )
461 if(
vec[i]->GetDefinition() == G4PionMinus::PionMinus() ||
462 vec[i]->GetDefinition() == G4PionPlus::PionPlus() ||
463 vec[i]->GetDefinition() == G4PionZero::PionZero() )
465 for(G4int i=0;
i<vecLen;
i++)
delete vec[i];
467#if G4VERSION_NUMBER < 1100
468 throw G4HadReentrentException(__FILE__, __LINE__,
470 throw G4HadronicException(__FILE__, __LINE__,
472 "FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon");
474 vec[
i]->SetSide( -3 );
475 ++backwardNucleonCount;
484 vecMass =
vec[
i]->GetMass()/CLHEP::GeV;
485 G4double ran = -std::log(1.0-G4UniformRand())/3.5;
486 if(
vec[i]->GetSide() == -2 )
488 if(
vec[i]->GetDefinition() == aKaonMinus ||
489 vec[i]->GetDefinition() == aKaonZeroL ||
490 vec[i]->GetDefinition() == aKaonZeroS ||
491 vec[i]->GetDefinition() == aKaonPlus ||
492 vec[i]->GetDefinition() == aPiMinus ||
493 vec[i]->GetDefinition() == aPiZero ||
494 vec[i]->GetDefinition() == aPiPlus )
497 pt = std::sqrt( std::pow( ran, 1.7 ) );
500 pt = std::sqrt( std::pow( ran, 1.2 ) );
503 if(
vec[i]->GetDefinition() == aPiMinus ||
504 vec[i]->GetDefinition() == aPiZero ||
505 vec[i]->GetDefinition() == aPiPlus )
508 pt = std::sqrt( std::pow( ran, 1.7 ) );
509 }
else if(
vec[i]->GetDefinition() == aKaonMinus ||
510 vec[i]->GetDefinition() == aKaonZeroL ||
511 vec[i]->GetDefinition() == aKaonZeroS ||
512 vec[i]->GetDefinition() == aKaonPlus )
515 pt = std::sqrt( std::pow( ran, 1.7 ) );
518 pt = std::sqrt( std::pow( ran, 1.5 ) );
521 pt = std::max( 0.001, pt );
522 vec[
i]->SetMomentum( pt*std::cos(
phi)*CLHEP::GeV, pt*std::sin(
phi)*CLHEP::GeV );
523 for( G4int j=0;
j<20; ++
j )binl[j] = j/(19.*pt);
524 if(
vec[i]->GetSide() > 0 )
525 et = pseudoParticle[0].GetTotalEnergy()/CLHEP::GeV;
527 et = pseudoParticle[1].GetTotalEnergy()/CLHEP::GeV;
533 eliminateThisParticle =
true;
534 resetEnergies =
true;
535 while( ++outerCounter < 3 )
537 for( l=1;
l<20; ++
l )
539 x = (binl[
l]+binl[
l-1])/2.;
540 pt = std::max( 0.001, pt );
542 dndl[
l] += dndl[
l-1];
544 dndl[
l] =
et * aspar/std::sqrt( std::pow((1.+aspar*
x*aspar*
x),3) )
545 * (binl[
l]-binl[
l-1]) / std::sqrt( pt*
x*
et*pt*
x*
et + pt*pt + vecMass*vecMass )
549 vec[
i]->SetMomentum( pt*std::cos(
phi)*CLHEP::GeV, pt*std::sin(
phi)*CLHEP::GeV );
553 while( ++innerCounter < 7 )
555 ran = G4UniformRand()*dndl[19];
557 while(l<19 && ran>=dndl[l])
l++;
558 x = std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
559 if(
vec[i]->GetSide() < 0 )
x *= -1.;
560 vec[
i]->SetMomentum(
x*
et*CLHEP::GeV );
561 totalEnergy = std::sqrt(
x*
et*
x*
et + pt*pt + vecMass*vecMass );
562 vec[
i]->SetTotalEnergy( totalEnergy*CLHEP::GeV );
563 kineticEnergy =
vec[
i]->GetKineticEnergy()/CLHEP::GeV;
564 if(
vec[i]->GetSide() > 0 )
566 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy )
568 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
i]);
569 forwardKinetic += kineticEnergy;
570 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
571 pseudoParticle[6].SetMomentum( 0.0 );
572 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
573 if( pseudoParticle[6].GetMomentum().
y()/CLHEP::MeV < 0.0 )
phi = CLHEP::twopi -
phi;
574 phi += CLHEP::pi + normal()*CLHEP::pi/12.0;
575 if(
phi > CLHEP::twopi )
phi -= CLHEP::twopi;
578 eliminateThisParticle =
false;
579 resetEnergies =
false;
582 if( innerCounter > 5 )
break;
583 if( backwardEnergy >= vecMass )
585 vec[
i]->SetSide( -1 );
586 forwardEnergy += vecMass;
587 backwardEnergy -= vecMass;
591 if( extraNucleonCount > 19 )
593 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
594 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy )
596 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
i]);
597 backwardKinetic += kineticEnergy;
598 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
599 pseudoParticle[6].SetMomentum( 0.0 );
600 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
601 if( pseudoParticle[6].GetMomentum().
y()/CLHEP::MeV < 0.0 )
phi = CLHEP::twopi -
phi;
602 phi += CLHEP::pi + normal() * CLHEP::pi / 12.0;
603 if(
phi > CLHEP::twopi )
phi -= CLHEP::twopi;
606 eliminateThisParticle =
false;
607 resetEnergies =
false;
610 if( innerCounter > 5 )
break;
611 if( forwardEnergy >= vecMass )
613 vec[
i]->SetSide( 1 );
614 forwardEnergy -= vecMass;
615 backwardEnergy += vecMass;
631 forwardKinetic = 0.0;
632 backwardKinetic = 0.0;
633 pseudoParticle[4].SetZero();
634 pseudoParticle[5].SetZero();
635 for( l=i+1;
l<vecLen; ++
l )
637 if(
vec[l]->GetSide() > 0 ||
638 vec[l]->GetDefinition() == aKaonMinus ||
639 vec[l]->GetDefinition() == aKaonZeroL ||
640 vec[l]->GetDefinition() == aKaonZeroS ||
641 vec[l]->GetDefinition() == aKaonPlus ||
642 vec[l]->GetDefinition() == aPiMinus ||
643 vec[l]->GetDefinition() == aPiZero ||
644 vec[l]->GetDefinition() == aPiPlus )
646 G4double tempMass =
vec[
l]->GetMass()/CLHEP::MeV;
647 totalEnergy = 0.95*
vec[
l]->GetTotalEnergy()/CLHEP::MeV + 0.05*tempMass;
648 totalEnergy = std::max( tempMass, totalEnergy );
649 vec[
l]->SetTotalEnergy( totalEnergy*CLHEP::MeV );
650 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) );
651 pp1 =
vec[
l]->GetMomentum().mag()/CLHEP::MeV;
652 if( pp1 < 1.0e-6*CLHEP::GeV )
654 G4double rthnve = CLHEP::pi*G4UniformRand();
655 G4double phinve = CLHEP::twopi*G4UniformRand();
656 G4double srth = std::sin(rthnve);
657 vec[
l]->SetMomentum( pp*srth*std::cos(phinve)*CLHEP::MeV,
658 pp*srth*std::sin(phinve)*CLHEP::MeV,
659 pp*std::cos(rthnve)*CLHEP::MeV ) ;
661 vec[
l]->SetMomentum(
vec[l]->GetMomentum() * (pp/pp1) );
663 G4double
px =
vec[
l]->GetMomentum().x()/CLHEP::MeV;
664 G4double
py =
vec[
l]->GetMomentum().y()/CLHEP::MeV;
665 pt = std::max( 1.0, std::sqrt( px*px + py*py ) )/CLHEP::GeV;
666 if(
vec[l]->GetSide() > 0 )
668 forwardKinetic +=
vec[
l]->GetKineticEnergy()/CLHEP::GeV;
669 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
l]);
671 backwardKinetic +=
vec[
l]->GetKineticEnergy()/CLHEP::GeV;
672 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
l]);
679 if( eliminateThisParticle &&
vec[i]->GetMayBeKilled())
681 if(
vec[i]->GetSide() > 0 )
684 forwardEnergy += vecMass;
686 if(
vec[i]->GetSide() == -2 )
689 backwardEnergy -= vecMass;
692 backwardEnergy += vecMass;
694 for( G4int j=i;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
695 G4ReactionProduct *temp =
vec[vecLen-1];
698 if( --vecLen == 0 )
return false;
699 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
700 pseudoParticle[6].SetMomentum( 0.0 );
701 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
702 if( pseudoParticle[6].GetMomentum().
y()/CLHEP::MeV < 0.0 )
phi = CLHEP::twopi -
phi;
703 phi += CLHEP::pi + normal() * CLHEP::pi / 12.0;
704 if(
phi > CLHEP::twopi )
phi -= CLHEP::twopi;
714 G4double
phi = G4UniformRand()*CLHEP::twopi;
715 G4double ran = -std::log(1.0-G4UniformRand());
716 if( currentParticle.GetDefinition() == aPiMinus ||
717 currentParticle.GetDefinition() == aPiZero ||
718 currentParticle.GetDefinition() == aPiPlus )
721 pt = std::sqrt( std::pow( ran/6.0, 1.7 ) );
722 }
else if( currentParticle.GetDefinition() == aKaonMinus ||
723 currentParticle.GetDefinition() == aKaonZeroL ||
724 currentParticle.GetDefinition() == aKaonZeroS ||
725 currentParticle.GetDefinition() == aKaonPlus )
728 pt = std::sqrt( std::pow( ran/5.0, 1.4 ) );
731 pt = std::sqrt( std::pow( ran/4.0, 1.2 ) );
733 for( G4int j=0;
j<20; ++
j )binl[j] = j/(19.*pt);
734 currentParticle.SetMomentum( pt*std::cos(
phi)*CLHEP::GeV, pt*std::sin(
phi)*CLHEP::GeV );
735 et = pseudoParticle[0].GetTotalEnergy()/CLHEP::GeV;
737 vecMass = currentParticle.GetMass()/CLHEP::GeV;
738 for( l=1;
l<20; ++
l )
740 x = (binl[
l]+binl[
l-1])/2.;
742 dndl[
l] += dndl[
l-1];
744 dndl[
l] = aspar/std::sqrt( std::pow((1.+
sqr(aspar*
x)),3) ) *
745 (binl[
l]-binl[
l-1]) *
et / std::sqrt( pt*
x*
et*pt*
x*
et + pt*pt + vecMass*vecMass ) +
748 ran = G4UniformRand()*dndl[19];
750 while( (l<20) && (ran>dndl[l]) )
l++;
751 l = std::min( 19, l );
752 x = std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
753 currentParticle.SetMomentum(
x*
et*CLHEP::GeV );
754 if( forwardEnergy < forwardKinetic )
755 totalEnergy = vecMass + 0.04*std::fabs(normal());
757 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
758 currentParticle.SetTotalEnergy( totalEnergy*CLHEP::GeV );
759 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*CLHEP::GeV;
760 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
761 if( pp1 < 1.0e-6*CLHEP::GeV )
763 G4double rthnve = CLHEP::pi*G4UniformRand();
764 G4double phinve = CLHEP::twopi*G4UniformRand();
765 G4double srth = std::sin(rthnve);
766 currentParticle.SetMomentum( pp*srth*std::cos(phinve)*CLHEP::MeV,
767 pp*srth*std::sin(phinve)*CLHEP::MeV,
768 pp*std::cos(rthnve)*CLHEP::MeV );
770 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
772 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
777 if( backwardNucleonCount < 18 )
779 targetParticle.SetSide( -3 );
780 ++backwardNucleonCount;
787 vecMass = targetParticle.GetMass()/CLHEP::GeV;
788 ran = -std::log(1.0-G4UniformRand());
790 pt = std::max( 0.001, std::sqrt( std::pow( ran/4.0, 1.2 ) ) );
791 targetParticle.SetMomentum( pt*std::cos(
phi)*CLHEP::GeV, pt*std::sin(
phi)*CLHEP::GeV );
792 for( G4int j=0;
j<20; ++
j )binl[j] = (j-1.)/(19.*
pt);
793 et = pseudoParticle[1].GetTotalEnergy()/CLHEP::GeV;
796 eliminateThisParticle =
true;
797 resetEnergies =
true;
798 while( ++outerCounter < 3 )
800 for( l=1;
l<20; ++
l )
802 x = (binl[
l]+binl[
l-1])/2.;
804 dndl[
l] += dndl[
l-1];
806 dndl[
l] = aspar/std::sqrt( std::pow((1.+aspar*
x*aspar*
x),3) ) *
807 (binl[
l]-binl[
l-1])*
et / std::sqrt( pt*
x*
et*pt*
x*
et+pt*pt+vecMass*vecMass ) +
811 while( ++innerCounter < 7 )
814 ran = G4UniformRand()*dndl[19];
815 while( ( l < 20 ) && ( ran >= dndl[l] ) )
l++;
816 l = std::min( 19, l );
817 x = std::min( 1.0, pt*(binl[l-1] + G4UniformRand()*(binl[l]-binl[l-1])/2.) );
818 if( targetParticle.GetSide() < 0 )
x *= -1.;
819 targetParticle.SetMomentum(
x*
et*CLHEP::GeV );
820 totalEnergy = std::sqrt(
x*
et*
x*
et + pt*pt + vecMass*vecMass );
821 targetParticle.SetTotalEnergy( totalEnergy*CLHEP::GeV );
822 if( targetParticle.GetSide() < 0 )
824 if( extraNucleonCount > 19 )
x=0.999;
825 G4double xxx = 0.95+0.05*extraNucleonCount/20.0;
826 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy )
828 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
829 backwardKinetic += totalEnergy - vecMass;
830 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
831 pseudoParticle[6].SetMomentum( 0.0 );
832 phi = pseudoParticle[6].Angle( pseudoParticle[8] );
833 if( pseudoParticle[6].GetMomentum().
y()/CLHEP::MeV < 0.0 )
phi = CLHEP::twopi -
phi;
834 phi += CLHEP::pi + normal() * CLHEP::pi / 12.0;
835 if(
phi > CLHEP::twopi )
phi -= CLHEP::twopi;
838 eliminateThisParticle =
false;
839 resetEnergies =
false;
842 if( innerCounter > 5 )
break;
843 if( forwardEnergy >= vecMass )
845 targetParticle.SetSide( 1 );
846 forwardEnergy -= vecMass;
847 backwardEnergy += vecMass;
850 G4ThreeVector
momentum = targetParticle.GetMomentum();
857 if( forwardEnergy < forwardKinetic )
858 totalEnergy = vecMass + 0.04*std::fabs(normal());
860 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
861 targetParticle.SetTotalEnergy( totalEnergy*CLHEP::GeV );
862 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*CLHEP::GeV;
863 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
864 if( pp1 < 1.0e-6*CLHEP::GeV )
866 G4double rthnve = CLHEP::pi*G4UniformRand();
867 G4double phinve = CLHEP::twopi*G4UniformRand();
868 G4double srth = std::sin(rthnve);
869 targetParticle.SetMomentum( pp*srth*std::cos(phinve)*CLHEP::MeV,
870 pp*srth*std::sin(phinve)*CLHEP::MeV,
871 pp*std::cos(rthnve)*CLHEP::MeV );
874 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
876 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
878 eliminateThisParticle =
false;
879 resetEnergies =
false;
890 forwardKinetic = backwardKinetic = 0.0;
891 pseudoParticle[4].SetZero();
892 pseudoParticle[5].SetZero();
893 for( l=0;
l<vecLen; ++
l )
895 if(
vec[l]->GetSide() > 0 ||
896 vec[l]->GetDefinition() == aKaonMinus ||
897 vec[l]->GetDefinition() == aKaonZeroL ||
898 vec[l]->GetDefinition() == aKaonZeroS ||
899 vec[l]->GetDefinition() == aKaonPlus ||
900 vec[l]->GetDefinition() == aPiMinus ||
901 vec[l]->GetDefinition() == aPiZero ||
902 vec[l]->GetDefinition() == aPiPlus )
904 G4double tempMass =
vec[
l]->GetMass()/CLHEP::GeV;
906 std::max( tempMass, 0.95*
vec[l]->GetTotalEnergy()/CLHEP::GeV + 0.05*tempMass );
907 vec[
l]->SetTotalEnergy( totalEnergy*CLHEP::GeV );
908 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) )*CLHEP::GeV;
909 pp1 =
vec[
l]->GetMomentum().mag()/CLHEP::MeV;
910 if( pp1 < 1.0e-6*CLHEP::GeV )
912 G4double rthnve = CLHEP::pi*G4UniformRand();
913 G4double phinve = CLHEP::twopi*G4UniformRand();
914 G4double srth = std::sin(rthnve);
915 vec[
l]->SetMomentum( pp*srth*std::cos(phinve)*CLHEP::MeV,
916 pp*srth*std::sin(phinve)*CLHEP::MeV,
917 pp*std::cos(rthnve)*CLHEP::MeV );
920 vec[
l]->SetMomentum(
vec[l]->GetMomentum() * (pp/pp1) );
922 pt = std::max( 0.001*CLHEP::GeV, std::sqrt(
sqr(
vec[l]->GetMomentum().
x()/CLHEP::MeV) +
923 sqr(
vec[l]->GetMomentum().
y()/CLHEP::MeV) ) )/CLHEP::GeV;
924 if(
vec[l]->GetSide() > 0)
926 forwardKinetic +=
vec[
l]->GetKineticEnergy()/CLHEP::GeV;
927 pseudoParticle[4] = pseudoParticle[4] + (*
vec[
l]);
929 backwardKinetic +=
vec[
l]->GetKineticEnergy()/CLHEP::GeV;
930 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
l]);
946 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] );
947 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
948 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
949 if( backwardNucleonCount == 1 )
952 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/CLHEP::GeV );
953 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() );
954 vecMass = targetParticle.GetMass()/CLHEP::GeV;
955 totalEnergy = ekin+vecMass;
956 targetParticle.SetTotalEnergy( totalEnergy*CLHEP::GeV );
957 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*CLHEP::GeV;
958 pp1 = pseudoParticle[6].GetMomentum().mag()/CLHEP::MeV;
959 if( pp1 < 1.0e-6*CLHEP::GeV )
961 rthnve = CLHEP::pi*G4UniformRand();
962 phinve = CLHEP::twopi*G4UniformRand();
963 G4double srth = std::sin(rthnve);
964 targetParticle.SetMomentum( pp*srth*std::cos(phinve)*CLHEP::MeV,
965 pp*srth*std::sin(phinve)*CLHEP::MeV,
966 pp*std::cos(rthnve)*CLHEP::MeV );
968 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) );
970 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
974 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
975 const G4double gpar[] = { 2.6, 2.6, 1.80, 1.30, 1.20 };
979 if (backwardNucleonCount < 5)
981 tempCount = backwardNucleonCount;
991 if( targetParticle.GetSide() == -3 )
992 rmb0 += targetParticle.GetMass()/CLHEP::GeV;
993 for( i=0;
i<vecLen; ++
i )
995 if(
vec[i]->GetSide() == -3 )rmb0 +=
vec[
i]->GetMass()/CLHEP::GeV;
997 rmb = rmb0 + std::pow(-std::log(1.0-G4UniformRand()),cpar[tempCount]) / gpar[tempCount];
998 totalEnergy = pseudoParticle[6].GetTotalEnergy()/CLHEP::GeV;
999 vecMass = std::min( rmb, totalEnergy );
1000 pseudoParticle[6].SetMass( vecMass*CLHEP::GeV );
1001 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*CLHEP::GeV;
1002 pp1 = pseudoParticle[6].GetMomentum().mag()/CLHEP::MeV;
1003 if( pp1 < 1.0e-6*CLHEP::GeV )
1005 rthnve = CLHEP::pi * G4UniformRand();
1006 phinve = CLHEP::twopi * G4UniformRand();
1007 G4double srth = std::sin(rthnve);
1008 pseudoParticle[6].SetMomentum( -pp*srth*std::cos(phinve)*CLHEP::MeV,
1009 -pp*srth*std::sin(phinve)*CLHEP::MeV,
1010 -pp*std::cos(rthnve)*CLHEP::MeV );
1013 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) );
1015 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1016 tempV.Initialize( backwardNucleonCount );
1018 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle );
1019 for( i=0;
i<vecLen; ++
i )
1021 if(
vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++,
vec[i] );
1023 if( tempLen != backwardNucleonCount )
1025 G4cerr <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
1026 G4cerr <<
"tempLen = " << tempLen;
1027 G4cerr <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
1028 G4cerr <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
1029 G4cerr <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
1030 for( i=0;
i<vecLen; ++
i )
1031 G4cerr <<
"particle #" << i <<
" side = " <<
vec[i]->GetSide() << G4endl;
1032 throw std::runtime_error(
"FullModelReactionDynamics::GenerateXandPt: "
1033 "tempLen is not the same as backwardNucleonCount");
1035 constantCrossSection =
true;
1039 wgt = GenerateNBodyEvent(
1040 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen );
1042 if( targetParticle.GetSide() == -3 )
1044 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1046 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
1048 for( i=0;
i<vecLen; ++
i )
1050 if(
vec[i]->GetSide() == -3 )
1052 vec[
i]->Lorentz( *
vec[i], pseudoParticle[6] );
1053 pseudoParticle[5] = pseudoParticle[5] + (*
vec[
i]);
1062 if( vecLen == 0 )
return false;
1065 G4int numberofFinalStateNucleons = 0;
1066 if( currentParticle.GetDefinition() ==aProton ||
1067 currentParticle.GetDefinition() == aNeutron ||
1068 currentParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()||
1069 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1070 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1071 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1072 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1073 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1074 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1075 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
1077 if( targetParticle.GetDefinition() ==aProton ||
1078 targetParticle.GetDefinition() == aNeutron ||
1079 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1080 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1081 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1082 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1083 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1084 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1085 targetParticle.GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1086 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1087 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1088 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1089 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1090 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1091 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1092 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1093 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1094 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1095 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
1097 for( i=0;
i<vecLen; ++
i )
1099 if(
vec[i]->GetDefinition() ==aProton ||
1100 vec[i]->GetDefinition() == aNeutron ||
1101 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1102 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1103 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1104 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1105 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
1106 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
1107 vec[i]->GetDefinition() == G4SigmaMinus::SigmaMinus()) ++numberofFinalStateNucleons;
1108 if(
vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1109 if(
vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1110 if(
vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1111 if(
vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1112 if(
vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1113 if(
vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1114 if(
vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1115 if(
vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1116 if(
vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1117 vec[
i]->Lorentz( *
vec[i], pseudoParticle[1] );
1120 if(veryForward) numberofFinalStateNucleons++;
1121 numberofFinalStateNucleons = std::max( 1, numberofFinalStateNucleons );
1132 G4bool leadingStrangeParticleHasChanged =
true;
1135 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
1136 leadingStrangeParticleHasChanged =
false;
1137 if( leadingStrangeParticleHasChanged &&
1138 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) )
1139 leadingStrangeParticleHasChanged =
false;
1140 if( leadingStrangeParticleHasChanged )
1142 for( i=0;
i<vecLen;
i++ )
1144 if(
vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
1146 leadingStrangeParticleHasChanged =
false;
1151 if( leadingStrangeParticleHasChanged )
1154 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
1155 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
1156 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
1157 leadingStrangeParticle.GetDefinition() == aKaonPlus ||
1158 leadingStrangeParticle.GetDefinition() == aPiMinus ||
1159 leadingStrangeParticle.GetDefinition() == aPiZero ||
1160 leadingStrangeParticle.GetDefinition() == aPiPlus);
1161 G4bool targetTest =
false;
1172 if( (leadTest&&targetTest) || !(leadTest||targetTest) )
1174 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1175 targetHasChanged =
true;
1180 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() );
1181 incidentHasChanged =
false;
1187 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*CLHEP::GeV );
1188 pseudoParticle[3].SetMass( mOriginal*CLHEP::GeV );
1189 pseudoParticle[3].SetTotalEnergy(
1190 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*CLHEP::GeV );
1194 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
1196 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() )
diff = 1;
1197 if(numberofFinalStateNucleons == 1)
diff = 0;
1198 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 );
1199 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-
diff)*CLHEP::MeV );
1200 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-
diff)*CLHEP::MeV );
1202 G4double theoreticalKinetic =
1203 pseudoParticle[3].GetTotalEnergy()/CLHEP::MeV +
1204 pseudoParticle[4].GetTotalEnergy()/CLHEP::MeV -
1205 currentParticle.GetMass()/CLHEP::MeV -
1206 targetParticle.GetMass()/CLHEP::MeV;
1208 G4double simulatedKinetic =
1209 currentParticle.GetKineticEnergy()/CLHEP::MeV + targetParticle.GetKineticEnergy()/CLHEP::MeV;
1211 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1212 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] );
1213 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] );
1215 pseudoParticle[7].SetZero();
1216 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1217 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1219 for( i=0;
i<vecLen; ++
i )
1221 pseudoParticle[7] = pseudoParticle[7] + *
vec[
i];
1222 simulatedKinetic +=
vec[
i]->GetKineticEnergy()/CLHEP::MeV;
1223 theoreticalKinetic -=
vec[
i]->GetMass()/CLHEP::MeV;
1225 if( vecLen <= 16 && vecLen > 0 )
1230 G4ReactionProduct tempR[130];
1232 tempR[0] = currentParticle;
1233 tempR[1] = targetParticle;
1234 for( i=0;
i<vecLen; ++
i )tempR[i+2] = *
vec[i];
1235 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1236 tempV.Initialize( vecLen+2 );
1238 for( i=0;
i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
1239 constantCrossSection =
true;
1241 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/CLHEP::MeV+
1242 pseudoParticle[4].GetTotalEnergy()/CLHEP::MeV,
1243 constantCrossSection, tempV, tempLen );
1246 theoreticalKinetic = 0.0;
1247 for( i=0;
i<tempLen; ++
i )
1249 pseudoParticle[6].Lorentz( *tempV[i], pseudoParticle[4] );
1250 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy()/CLHEP::MeV;
1259 if( simulatedKinetic != 0.0 )
1261 wgt = (theoreticalKinetic)/simulatedKinetic;
1262 theoreticalKinetic = currentParticle.GetKineticEnergy()/CLHEP::MeV * wgt;
1263 simulatedKinetic = theoreticalKinetic;
1264 currentParticle.SetKineticEnergy( theoreticalKinetic*CLHEP::MeV );
1265 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
1266 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
1267 if( pp1 < 1.0e-6*CLHEP::GeV )
1269 rthnve = CLHEP::pi*G4UniformRand();
1270 phinve = CLHEP::twopi*G4UniformRand();
1271 currentParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
1272 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
1273 pp*std::cos(rthnve)*CLHEP::MeV );
1277 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
1279 theoreticalKinetic = targetParticle.GetKineticEnergy()/CLHEP::MeV * wgt;
1280 targetParticle.SetKineticEnergy( theoreticalKinetic*CLHEP::MeV );
1281 simulatedKinetic += theoreticalKinetic;
1282 pp = targetParticle.GetTotalMomentum()/CLHEP::MeV;
1283 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
1285 if( pp1 < 1.0e-6*CLHEP::GeV )
1287 rthnve = CLHEP::pi*G4UniformRand();
1288 phinve = CLHEP::twopi*G4UniformRand();
1289 targetParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
1290 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
1291 pp*std::cos(rthnve)*CLHEP::MeV );
1293 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
1295 for( i=0;
i<vecLen; ++
i )
1297 theoreticalKinetic =
vec[
i]->GetKineticEnergy()/CLHEP::MeV * wgt;
1298 simulatedKinetic += theoreticalKinetic;
1299 vec[
i]->SetKineticEnergy( theoreticalKinetic*CLHEP::MeV );
1300 pp =
vec[
i]->GetTotalMomentum()/CLHEP::MeV;
1301 pp1 =
vec[
i]->GetMomentum().mag()/CLHEP::MeV;
1302 if( pp1 < 1.0e-6*CLHEP::GeV )
1304 rthnve = CLHEP::pi*G4UniformRand();
1305 phinve = CLHEP::twopi*G4UniformRand();
1306 vec[
i]->SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
1307 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
1308 pp*std::cos(rthnve)*CLHEP::MeV );
1311 vec[
i]->SetMomentum(
vec[i]->GetMomentum() * (pp/pp1) );
1315 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(),
1316 modifiedOriginal, originalIncident, targetNucleus,
1317 currentParticle, targetParticle,
vec, vecLen );
1324 if( atomicWeight >= 1.5 )
1331 G4double epnb, edta;
1335 epnb = targetNucleus.GetPNBlackTrackEnergy();
1336 edta = targetNucleus.GetDTABlackTrackEnergy();
1337 const G4double pnCutOff = 0.001;
1338 const G4double dtaCutOff = 0.001;
1339 const G4double kineticMinimum = 1.e-6;
1340 const G4double kineticFactor = -0.010;
1341 G4double sprob = 0.0;
1342 const G4double ekIncident = originalIncident->GetKineticEnergy()/CLHEP::GeV;
1343 if( ekIncident >= 5.0 )sprob = std::min( 1.0, 0.6*std::log(ekIncident-4.0) );
1344 if( epnb >= pnCutOff )
1346 npnb =
Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
1347 if( numberofFinalStateNucleons + npnb > atomicWeight )
1348 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons);
1349 npnb = std::min( npnb, 127-vecLen );
1351 if( edta >= dtaCutOff )
1353 ndta =
Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
1354 ndta = std::min( ndta, 127-vecLen );
1356 G4double spall = numberofFinalStateNucleons;
1359 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
1360 modifiedOriginal, spall, targetNucleus,
1375 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
1376 currentParticle.SetTOF( 1.0-500.0*std::exp(-ekOriginal/0.04)*std::log(G4UniformRand()) );
1378 currentParticle.SetTOF( 1.0 );
1383void FullModelReactionDynamics::SuppressChargedPions(
1384 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
1386 const G4ReactionProduct &modifiedOriginal,
1387 G4ReactionProduct ¤tParticle,
1389 const G4Nucleus &targetNucleus,
1390 G4bool &incidentHasChanged
1398 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
1399 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1400 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/CLHEP::GeV;
1403 G4ParticleDefinition *aProton = G4Proton::Proton();
1404 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1405 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1406 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1407 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1408 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1410 const G4bool antiTest =
1411 modifiedOriginal.GetDefinition() != anAntiProton &&
1412 modifiedOriginal.GetDefinition() != anAntiNeutron;
1415 currentParticle.GetDefinition() == aPiPlus ||
1416 currentParticle.GetDefinition() == aPiMinus ) &&
1417 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1418 ( G4UniformRand() <= atomicWeight/300.0 ) )
1420 if( G4UniformRand() > atomicNumber/atomicWeight )
1421 currentParticle.SetDefinitionAndUpdateE( aNeutron );
1423 currentParticle.SetDefinitionAndUpdateE( aProton );
1424 incidentHasChanged =
true;
1440 for( G4int i=0;
i<vecLen; ++
i )
1444 vec[i]->GetDefinition() == aPiPlus ||
1445 vec[i]->GetDefinition() == aPiMinus ) &&
1446 ( G4UniformRand() <= (10.0-pOriginal)/6.0 ) &&
1447 ( G4UniformRand() <= atomicWeight/300.0 ) )
1449 if( G4UniformRand() > atomicNumber/atomicWeight )
1450 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
1452 vec[
i]->SetDefinitionAndUpdateE( aProton );
1459G4bool FullModelReactionDynamics::TwoCluster(
1460 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
1462 G4ReactionProduct &modifiedOriginal,
1463 const G4HadProjectile *originalIncident,
1464 G4ReactionProduct ¤tParticle,
1465 G4ReactionProduct &targetParticle,
1466 const G4Nucleus &targetNucleus,
1467 G4bool &incidentHasChanged,
1468 G4bool &targetHasChanged,
1470 G4ReactionProduct &leadingStrangeParticle )
1486 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1487 G4ParticleDefinition *aProton = G4Proton::Proton();
1488 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1489 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1490 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1491 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
1492 const G4double protonMass = aProton->GetPDGMass()/CLHEP::MeV;
1493 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/CLHEP::GeV;
1494 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/CLHEP::GeV;
1495 const G4double mOriginal = modifiedOriginal.GetMass()/CLHEP::GeV;
1496 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/CLHEP::GeV;
1497 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/CLHEP::GeV;
1498 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
1499 targetMass*targetMass +
1500 2.0*targetMass*etOriginal );
1501 G4double currentMass = currentParticle.GetMass()/CLHEP::GeV;
1502 targetMass = targetParticle.GetMass()/CLHEP::GeV;
1504 if( currentMass == 0.0 && targetMass == 0.0 )
1506 G4double ek = currentParticle.GetKineticEnergy();
1507 G4ThreeVector
m = currentParticle.GetMomentum();
1508 currentParticle = *
vec[0];
1509 targetParticle = *
vec[1];
1510 for( i=0;
i<(vecLen-2); ++
i )*
vec[i] = *
vec[i+2];
1513 for(G4int i=0;
i<vecLen;
i++)
delete vec[i];
1515#if G4VERSION_NUMBER < 1100
1516 throw G4HadReentrentException(__FILE__, __LINE__,
1518 throw G4HadronicException(__FILE__, __LINE__,
1520 "FullModelReactionDynamics::TwoCluster: Negative number of particles");
1522 delete vec[vecLen-1];
1523 delete vec[vecLen-2];
1525 currentMass = currentParticle.GetMass()/CLHEP::GeV;
1526 targetMass = targetParticle.GetMass()/CLHEP::GeV;
1527 incidentHasChanged =
true;
1528 targetHasChanged =
true;
1529 currentParticle.SetKineticEnergy( ek );
1530 currentParticle.SetMomentum( m );
1532 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
1533 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1539 G4int forwardCount = 1;
1540 currentParticle.SetSide( 1 );
1541 G4double forwardMass = currentParticle.GetMass()/CLHEP::GeV;
1544 G4int backwardCount = 1;
1545 targetParticle.SetSide( -1 );
1546 G4double backwardMass = targetParticle.GetMass()/CLHEP::GeV;
1548 for( i=0;
i<vecLen; ++
i )
1550 if(
vec[i]->GetSide() < 0 )
vec[
i]->SetSide( -1 );
1553 if(
vec[i]->GetSide() == -1 )
1556 backwardMass +=
vec[
i]->GetMass()/CLHEP::GeV;
1561 forwardMass +=
vec[
i]->GetMass()/CLHEP::GeV;
1567 G4double term1 = std::log(centerofmassEnergy*centerofmassEnergy);
1568 if(term1 < 0) term1 = 0.0001;
1569 const G4double afc = 0.312 + 0.2 * std::log(term1);
1571 if( centerofmassEnergy < 2.0+G4UniformRand() )
1572 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount+vecLen+2)/2.0;
1574 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2*backwardCount);
1575 if( xtarg <= 0.0 )xtarg = 0.01;
1576 G4int nuclearExcitationCount =
Poisson( xtarg );
1577 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
1579 if( nuclearExcitationCount > 0 )
1581 G4int momentumBin = std::min( 4, G4int(pOriginal/3.0) );
1582 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
1588 for( i=0;
i<nuclearExcitationCount; ++
i )
1590 G4ReactionProduct* pVec =
new G4ReactionProduct();
1591 if( G4UniformRand() < nucsup[momentumBin] )
1593 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight )
1595 pVec->SetDefinition( aProton );
1597 pVec->SetDefinition( aNeutron );
1601 G4double ran = G4UniformRand();
1603 pVec->SetDefinition( aPiPlus );
1604 else if( ran < 0.6819 )
1605 pVec->SetDefinition( aPiZero );
1607 pVec->SetDefinition( aPiMinus );
1609 pVec->SetSide( -2 );
1611 pVec->SetNewlyAdded(
true );
1612 vec.SetElement( vecLen++, pVec );
1617 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1618 G4bool secondaryDeleted;
1620 while( eAvailable <= 0.0 )
1622 secondaryDeleted =
false;
1623 for( i=(vecLen-1);
i>=0; --
i )
1625 if(
vec[i]->GetSide() == 1 &&
vec[i]->GetMayBeKilled())
1628 for( G4int j=i;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1630 forwardMass -=
pMass;
1631 secondaryDeleted =
true;
1634 else if(
vec[i]->GetSide() == -1 &&
vec[i]->GetMayBeKilled())
1637 for( G4int j=i;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1639 backwardMass -=
pMass;
1640 secondaryDeleted =
true;
1644 if( secondaryDeleted )
1646 G4ReactionProduct *temp =
vec[vecLen-1];
1657 if( targetParticle.GetSide() == -1 )
1659 pMass = targetParticle.GetMass()/CLHEP::GeV;
1660 targetParticle = *
vec[0];
1661 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1663 backwardMass -=
pMass;
1664 secondaryDeleted =
true;
1666 else if( targetParticle.GetSide() == 1 )
1668 pMass = targetParticle.GetMass()/CLHEP::GeV;
1669 targetParticle = *
vec[0];
1670 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1672 forwardMass -=
pMass;
1673 secondaryDeleted =
true;
1675 if( secondaryDeleted )
1677 G4ReactionProduct *temp =
vec[vecLen-1];
1684 if( currentParticle.GetSide() == -1 )
1686 pMass = currentParticle.GetMass()/CLHEP::GeV;
1687 currentParticle = *
vec[0];
1688 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1690 backwardMass -=
pMass;
1691 secondaryDeleted =
true;
1693 else if( currentParticle.GetSide() == 1 )
1695 pMass = currentParticle.GetMass()/CLHEP::GeV;
1696 currentParticle = *
vec[0];
1697 for( G4int j=0;
j<(vecLen-1); ++
j )*
vec[j] = *
vec[j+1];
1699 forwardMass -=
pMass;
1700 secondaryDeleted =
true;
1702 if( secondaryDeleted )
1704 G4ReactionProduct *temp =
vec[vecLen-1];
1712 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
1721 G4double rmc = 0.0, rmd = 0.0;
1722 const G4double cpar[] = { 0.6, 0.6, 0.35, 0.15, 0.10 };
1723 const G4double gpar[] = { 2.6, 2.6, 1.8, 1.30, 1.20 };
1725 if( forwardCount == 0)
return false;
1727 if( forwardCount == 1 )rmc = forwardMass;
1731 G4int ntc = std::max(1, std::min(5,forwardCount))-1;
1732 rmc = forwardMass + std::pow(-std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1734 if( backwardCount == 1 )rmd = backwardMass;
1738 G4int ntc = std::max(1, std::min(5,backwardCount));
1739 rmd = backwardMass + std::pow(-std::log(1.0-G4UniformRand()),cpar[ntc-1])/gpar[ntc-1];
1741 while( rmc+rmd > centerofmassEnergy )
1743 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
1745 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
1751 rmc = 0.1*forwardMass + 0.9*rmc;
1752 rmd = 0.1*backwardMass + 0.9*rmd;
1767 G4ReactionProduct pseudoParticle[8];
1768 for( i=0;
i<8; ++
i )pseudoParticle[i].SetZero();
1770 pseudoParticle[1].SetMass( mOriginal*CLHEP::GeV );
1771 pseudoParticle[1].SetTotalEnergy( etOriginal*CLHEP::GeV );
1772 pseudoParticle[1].SetMomentum( 0.0, 0.0, pOriginal*CLHEP::GeV );
1774 pseudoParticle[2].SetMass( protonMass*CLHEP::MeV );
1775 pseudoParticle[2].SetTotalEnergy( protonMass*CLHEP::MeV );
1776 pseudoParticle[2].SetMomentum( 0.0, 0.0, 0.0 );
1780 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1781 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[0] );
1782 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
1784 const G4double pfMin = 0.0001;
1785 G4double
pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
1787 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
1788 pf = std::sqrt( std::max(pf,pfMin) )/(2.0*centerofmassEnergy);
1792 pseudoParticle[3].SetMass( rmc*CLHEP::GeV );
1793 pseudoParticle[3].SetTotalEnergy( std::sqrt(pf*pf+rmc*rmc)*CLHEP::GeV );
1795 pseudoParticle[4].SetMass( rmd*CLHEP::GeV );
1796 pseudoParticle[4].SetTotalEnergy( std::sqrt(pf*pf+rmd*rmd)*CLHEP::GeV );
1800 const G4double bMin = 0.01;
1801 const G4double b1 = 4.0;
1802 const G4double b2 = 1.6;
1803 G4double
t = std::log( 1.0-G4UniformRand() ) / std::max( bMin, b1+b2*std::log(pOriginal) );
1805 pseudoParticle[1].GetTotalEnergy()/CLHEP::GeV - pseudoParticle[3].GetTotalEnergy()/CLHEP::GeV;
1806 G4double pin = pseudoParticle[1].GetMomentum().mag()/CLHEP::GeV;
1807 G4double tacmin =
t1*
t1 - (pin-
pf)*(pin-pf);
1811 const G4double smallValue = 1.0e-10;
1812 G4double dumnve = 4.0*pin*
pf;
1813 if( dumnve == 0.0 )dumnve = smallValue;
1814 G4double ctet = std::max( -1.0, std::min( 1.0, 1.0+2.0*(t-tacmin)/dumnve ) );
1815 dumnve = std::max( 0.0, 1.0-ctet*ctet );
1816 G4double stet = std::sqrt(dumnve);
1817 G4double
phi = G4UniformRand() * CLHEP::twopi;
1821 pseudoParticle[3].SetMomentum( pf*stet*std::sin(
phi)*CLHEP::GeV,
1822 pf*stet*std::cos(
phi)*CLHEP::GeV,
1823 pf*ctet*CLHEP::GeV );
1824 pseudoParticle[4].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1828 G4double pp, pp1, rthnve, phinve;
1829 if( nuclearExcitationCount > 0 )
1831 const G4double ga = 1.2;
1832 G4double ekit1 = 0.04;
1833 G4double ekit2 = 0.6;
1834 if( ekOriginal <= 5.0 )
1836 ekit1 *= ekOriginal*ekOriginal/25.0;
1837 ekit2 *= ekOriginal*ekOriginal/25.0;
1839 const G4double
a = (1.0-ga)/(std::pow(ekit2,(1.0-ga)) - std::pow(ekit1,(1.0-ga)));
1840 for( i=0;
i<vecLen; ++
i )
1842 if(
vec[i]->GetSide() == -2 )
1845 std::pow( (G4UniformRand()*(1.0-ga)/
a+std::pow(ekit1,(1.0-ga))), (1.0/(1.0-ga)) );
1846 vec[
i]->SetKineticEnergy( kineticE*CLHEP::GeV );
1847 G4double vMass =
vec[
i]->GetMass()/CLHEP::MeV;
1848 G4double totalE = kineticE + vMass;
1849 pp = std::sqrt( std::abs(totalE*totalE-vMass*vMass) );
1850 G4double
cost = std::min( 1.0, std::max( -1.0, std::log(2.23*G4UniformRand()+0.383)/0.96 ) );
1851 G4double sint = std::sqrt( std::max( 0.0, (1.0-
cost*
cost) ) );
1852 phi = CLHEP::twopi*G4UniformRand();
1853 vec[
i]->SetMomentum( pp*sint*std::sin(
phi)*CLHEP::MeV,
1854 pp*sint*std::cos(
phi)*CLHEP::MeV,
1855 pp*
cost*CLHEP::MeV );
1856 vec[
i]->Lorentz( *
vec[i], pseudoParticle[0] );
1864 currentParticle.SetMomentum( pseudoParticle[3].GetMomentum() );
1865 currentParticle.SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1867 targetParticle.SetMomentum( pseudoParticle[4].GetMomentum() );
1868 targetParticle.SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1870 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
1871 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
1872 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
1874 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
1875 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
1876 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
1880 if( forwardCount > 1 )
1882 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1883 tempV.Initialize( forwardCount );
1884 G4bool constantCrossSection =
true;
1886 if( currentParticle.GetSide() == 1 )
1887 tempV.SetElement( tempLen++, ¤tParticle );
1888 if( targetParticle.GetSide() == 1 )
1889 tempV.SetElement( tempLen++, &targetParticle );
1890 for( i=0;
i<vecLen; ++
i )
1892 if(
vec[i]->GetSide() == 1 )
1895 tempV.SetElement( tempLen++,
vec[i] );
1898 vec[
i]->SetSide( -1 );
1905 wgt = GenerateNBodyEvent( pseudoParticle[3].GetMass()/CLHEP::MeV,
1906 constantCrossSection, tempV, tempLen );
1907 if( currentParticle.GetSide() == 1 )
1908 currentParticle.Lorentz( currentParticle, pseudoParticle[5] );
1909 if( targetParticle.GetSide() == 1 )
1910 targetParticle.Lorentz( targetParticle, pseudoParticle[5] );
1911 for( i=0;
i<vecLen; ++
i )
1913 if(
vec[i]->GetSide() == 1 )
vec[
i]->Lorentz( *
vec[i], pseudoParticle[5] );
1918 if( backwardCount > 1 )
1920 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
1921 tempV.Initialize( backwardCount );
1922 G4bool constantCrossSection =
true;
1924 if( currentParticle.GetSide() == -1 )
1925 tempV.SetElement( tempLen++, ¤tParticle );
1926 if( targetParticle.GetSide() == -1 )
1927 tempV.SetElement( tempLen++, &targetParticle );
1928 for( i=0;
i<vecLen; ++
i )
1930 if(
vec[i]->GetSide() == -1 )
1933 tempV.SetElement( tempLen++,
vec[i] );
1936 vec[
i]->SetSide( -2 );
1937 vec[
i]->SetKineticEnergy( 0.0 );
1938 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
1945 wgt = GenerateNBodyEvent( pseudoParticle[4].GetMass()/CLHEP::MeV,
1946 constantCrossSection, tempV, tempLen );
1947 if( currentParticle.GetSide() == -1 )
1948 currentParticle.Lorentz( currentParticle, pseudoParticle[6] );
1949 if( targetParticle.GetSide() == -1 )
1950 targetParticle.Lorentz( targetParticle, pseudoParticle[6] );
1951 for( i=0;
i<vecLen; ++
i )
1953 if(
vec[i]->GetSide() == -1 )
vec[
i]->Lorentz( *
vec[i], pseudoParticle[6] );
1961 G4int numberofFinalStateNucleons = 0;
1962 if( currentParticle.GetDefinition() ==aProton ||
1963 currentParticle.GetDefinition() == aNeutron ||
1964 currentParticle.GetDefinition() == aSigmaMinus||
1965 currentParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1966 currentParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1967 currentParticle.GetDefinition() == G4XiZero::XiZero()||
1968 currentParticle.GetDefinition() == G4XiMinus::XiMinus()||
1969 currentParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1970 currentParticle.GetDefinition() == G4Lambda::Lambda()) ++numberofFinalStateNucleons;
1971 currentParticle.Lorentz( currentParticle, pseudoParticle[2] );
1972 if( targetParticle.GetDefinition() ==aProton ||
1973 targetParticle.GetDefinition() == aNeutron ||
1974 targetParticle.GetDefinition() == G4Lambda::Lambda() ||
1975 targetParticle.GetDefinition() == G4XiZero::XiZero()||
1976 targetParticle.GetDefinition() == G4XiMinus::XiMinus()||
1977 targetParticle.GetDefinition() == G4OmegaMinus::OmegaMinus()||
1978 targetParticle.GetDefinition() == G4SigmaZero::SigmaZero()||
1979 targetParticle.GetDefinition() == G4SigmaPlus::SigmaPlus()||
1980 targetParticle.GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
1981 if( targetParticle.GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
1982 if( targetParticle.GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
1983 if( targetParticle.GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
1984 if( targetParticle.GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
1985 if( targetParticle.GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
1986 if( targetParticle.GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
1987 if( targetParticle.GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
1988 if( targetParticle.GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
1989 if( targetParticle.GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
1990 targetParticle.Lorentz( targetParticle, pseudoParticle[2] );
1991 for( i=0;
i<vecLen; ++
i )
1993 if(
vec[i]->GetDefinition() ==aProton ||
1994 vec[i]->GetDefinition() == aNeutron ||
1995 vec[i]->GetDefinition() == G4Lambda::Lambda() ||
1996 vec[i]->GetDefinition() == G4XiZero::XiZero() ||
1997 vec[i]->GetDefinition() == G4XiMinus::XiMinus() ||
1998 vec[i]->GetDefinition() == G4OmegaMinus::OmegaMinus() ||
1999 vec[i]->GetDefinition() == G4SigmaPlus::SigmaPlus()||
2000 vec[i]->GetDefinition() == G4SigmaZero::SigmaZero()||
2001 vec[i]->GetDefinition() == aSigmaMinus) ++numberofFinalStateNucleons;
2002 if(
vec[i]->GetDefinition() ==G4AntiProton::AntiProton()) --numberofFinalStateNucleons;
2003 if(
vec[i]->GetDefinition() ==G4AntiNeutron::AntiNeutron()) --numberofFinalStateNucleons;
2004 if(
vec[i]->GetDefinition() ==G4AntiSigmaMinus::AntiSigmaMinus()) --numberofFinalStateNucleons;
2005 if(
vec[i]->GetDefinition() ==G4AntiSigmaPlus::AntiSigmaPlus()) --numberofFinalStateNucleons;
2006 if(
vec[i]->GetDefinition() ==G4AntiSigmaZero::AntiSigmaZero()) --numberofFinalStateNucleons;
2007 if(
vec[i]->GetDefinition() ==G4AntiLambda::AntiLambda()) --numberofFinalStateNucleons;
2008 if(
vec[i]->GetDefinition() ==G4AntiXiZero::AntiXiZero()) --numberofFinalStateNucleons;
2009 if(
vec[i]->GetDefinition() ==G4AntiXiMinus::AntiXiMinus()) --numberofFinalStateNucleons;
2010 if(
vec[i]->GetDefinition() ==G4AntiOmegaMinus::AntiOmegaMinus()) --numberofFinalStateNucleons;
2011 vec[
i]->Lorentz( *
vec[i], pseudoParticle[2] );
2014 numberofFinalStateNucleons = std::max( 1, numberofFinalStateNucleons );
2030 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2032 else if( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() )
2036 for( i=0;
i<vecLen; ++
i )
2038 if(
vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() )
2047 G4double leadMass = leadingStrangeParticle.GetMass()/CLHEP::MeV;
2049 if( ((leadMass < protonMass) && (targetParticle.GetMass()/CLHEP::MeV < protonMass)) ||
2050 ((leadMass >= protonMass) && (targetParticle.GetMass()/CLHEP::MeV >= protonMass)) )
2052 ekin = targetParticle.GetKineticEnergy()/CLHEP::GeV;
2053 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
2054 targetParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2055 targetParticle.SetKineticEnergy( ekin*CLHEP::GeV );
2056 pp = targetParticle.GetTotalMomentum()/CLHEP::MeV;
2059 rthnve = CLHEP::pi*G4UniformRand();
2060 phinve = CLHEP::twopi*G4UniformRand();
2061 targetParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(rthnve)*CLHEP::MeV,
2062 pp*std::sin(rthnve)*std::sin(rthnve)*CLHEP::MeV,
2063 pp*std::cos(rthnve)*CLHEP::MeV );
2066 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2068 targetHasChanged =
true;
2072 ekin = currentParticle.GetKineticEnergy()/CLHEP::GeV;
2073 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
2074 currentParticle.SetDefinition( leadingStrangeParticle.GetDefinition() );
2075 currentParticle.SetKineticEnergy( ekin*CLHEP::GeV );
2076 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
2079 rthnve = CLHEP::pi*G4UniformRand();
2080 phinve = CLHEP::twopi*G4UniformRand();
2081 currentParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(rthnve)*CLHEP::MeV,
2082 pp*std::sin(rthnve)*std::sin(rthnve)*CLHEP::MeV,
2083 pp*std::cos(rthnve)*CLHEP::MeV );
2086 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2088 incidentHasChanged =
true;
2096 pseudoParticle[4].SetMass( mOriginal*CLHEP::GeV );
2097 pseudoParticle[4].SetTotalEnergy( etOriginal*CLHEP::GeV );
2098 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*CLHEP::GeV );
2100 const G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition();
2102 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() )
diff = 1;
2103 if(numberofFinalStateNucleons == 1)
diff = 0;
2104 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
2105 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-
diff)*CLHEP::MeV );
2106 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-
diff)*CLHEP::MeV );
2109 G4double theoreticalKinetic =
2110 pseudoParticle[4].GetTotalEnergy()/CLHEP::GeV + pseudoParticle[5].GetTotalEnergy()/CLHEP::GeV;
2112 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
2113 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
2114 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
2118 G4ReactionProduct tempR[130];
2120 tempR[0] = currentParticle;
2121 tempR[1] = targetParticle;
2122 for( i=0;
i<vecLen; ++
i )tempR[i+2] = *
vec[i];
2124 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
2125 tempV.Initialize( vecLen+2 );
2126 G4bool constantCrossSection =
true;
2128 for( i=0;
i<vecLen+2; ++
i )tempV.SetElement( tempLen++, &tempR[i] );
2133 wgt = GenerateNBodyEvent(
2134 pseudoParticle[4].GetTotalEnergy()/CLHEP::MeV+pseudoParticle[5].GetTotalEnergy()/CLHEP::MeV,
2135 constantCrossSection, tempV, tempLen );
2136 theoreticalKinetic = 0.0;
2137 for( i=0;
i<vecLen+2; ++
i )
2139 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
2140 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
2141 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
2142 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
2143 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/CLHEP::GeV;
2151 theoreticalKinetic -=
2152 ( currentParticle.GetMass()/CLHEP::GeV + targetParticle.GetMass()/CLHEP::GeV );
2153 for( i=0;
i<vecLen; ++
i )theoreticalKinetic -=
vec[i]->GetMass()/CLHEP::GeV;
2155 G4double simulatedKinetic =
2156 currentParticle.GetKineticEnergy()/CLHEP::GeV + targetParticle.GetKineticEnergy()/CLHEP::GeV;
2157 for( i=0;
i<vecLen; ++
i )simulatedKinetic +=
vec[i]->GetKineticEnergy()/CLHEP::GeV;
2163 if( simulatedKinetic != 0.0 )
2165 wgt = (theoreticalKinetic)/simulatedKinetic;
2166 currentParticle.SetKineticEnergy( wgt*currentParticle.GetKineticEnergy() );
2167 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
2168 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
2169 if( pp1 < 0.001*CLHEP::MeV )
2171 rthnve = CLHEP::pi * G4UniformRand();
2172 phinve = CLHEP::twopi * G4UniformRand();
2173 currentParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
2174 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
2175 pp*std::cos(rthnve)*CLHEP::MeV );
2178 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2180 targetParticle.SetKineticEnergy( wgt*targetParticle.GetKineticEnergy() );
2181 pp = targetParticle.GetTotalMomentum()/CLHEP::MeV;
2182 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
2183 if( pp1 < 0.001*CLHEP::MeV )
2185 rthnve = CLHEP::pi * G4UniformRand();
2186 phinve = CLHEP::twopi * G4UniformRand();
2187 targetParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
2188 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
2189 pp*std::cos(rthnve)*CLHEP::MeV );
2192 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2194 for( i=0;
i<vecLen; ++
i )
2196 vec[
i]->SetKineticEnergy( wgt*
vec[i]->GetKineticEnergy() );
2197 pp =
vec[
i]->GetTotalMomentum()/CLHEP::MeV;
2198 pp1 =
vec[
i]->GetMomentum().mag()/CLHEP::MeV;
2201 rthnve = CLHEP::pi * G4UniformRand();
2202 phinve = CLHEP::twopi * G4UniformRand();
2204 vec[
i]->SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
2205 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
2206 pp*std::cos(rthnve)*CLHEP::MeV );
2209 vec[
i]->SetMomentum(
vec[i]->GetMomentum() * (pp/pp1) );
2213 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
2214 modifiedOriginal, originalIncident, targetNucleus,
2215 currentParticle, targetParticle,
vec, vecLen );
2221 if( atomicWeight >= 1.5 )
2228 G4double epnb, edta;
2232 epnb = targetNucleus.GetPNBlackTrackEnergy();
2233 edta = targetNucleus.GetDTABlackTrackEnergy();
2234 const G4double pnCutOff = 0.001;
2235 const G4double dtaCutOff = 0.001;
2236 const G4double kineticMinimum = 1.e-6;
2237 const G4double kineticFactor = -0.005;
2239 G4double sprob = 0.0;
2240 const G4double ekIncident = originalIncident->GetKineticEnergy()/CLHEP::GeV;
2241 if( ekIncident >= 5.0 )sprob = std::min( 1.0, 0.6*std::log(ekIncident-4.0) );
2243 if( epnb >= pnCutOff )
2245 npnb =
Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
2246 if( numberofFinalStateNucleons + npnb > atomicWeight )
2247 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
2248 npnb = std::min( npnb, 127-vecLen );
2250 if( edta >= dtaCutOff )
2252 ndta =
Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
2253 ndta = std::min( ndta, 127-vecLen );
2255 G4double spall = numberofFinalStateNucleons;
2258 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2259 modifiedOriginal, spall, targetNucleus,
2269 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2270 currentParticle.SetTOF( 1.0-500.0*std::exp(-ekOriginal/0.04)*std::log(G4UniformRand()) );
2272 currentParticle.SetTOF( 1.0 );
2278void FullModelReactionDynamics::TwoBody(
2279 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2281 G4ReactionProduct &modifiedOriginal,
2282 const G4DynamicParticle *,
2283 G4ReactionProduct ¤tParticle,
2284 G4ReactionProduct &targetParticle,
2285 const G4Nucleus &targetNucleus,
2298 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2299 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2300 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2301 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2302 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2303 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
2304 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
2307 static const G4double expxu = 82.;
2308 static const G4double expxl = -expxu;
2310 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/CLHEP::GeV;
2311 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/CLHEP::GeV;
2312 G4double currentMass = currentParticle.GetMass()/CLHEP::GeV;
2313 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/CLHEP::GeV;
2315 targetMass = targetParticle.GetMass()/CLHEP::GeV;
2316 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
2318 G4double etCurrent = currentParticle.GetTotalEnergy()/CLHEP::GeV;
2319 G4double pCurrent = currentParticle.GetTotalMomentum()/CLHEP::GeV;
2321 G4double cmEnergy = std::sqrt( currentMass*currentMass +
2322 targetMass*targetMass +
2323 2.0*targetMass*etCurrent );
2331 if( (pCurrent < 0.1) || (cmEnergy < 0.01) )
2333 targetParticle.SetMass( 0.0 );
2366 G4double
pf = cmEnergy*cmEnergy + targetMass*targetMass - currentMass*currentMass;
2367 pf =
pf*
pf - 4*cmEnergy*cmEnergy*targetMass*targetMass;
2372 for(G4int i=0;
i<vecLen;
i++)
delete vec[i];
2374 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
2377 pf = std::sqrt( pf ) / ( 2.0*cmEnergy );
2381 G4ReactionProduct pseudoParticle[3];
2407 pseudoParticle[0].SetMass( currentMass*CLHEP::GeV );
2408 pseudoParticle[0].SetTotalEnergy( etCurrent*CLHEP::GeV );
2409 pseudoParticle[0].SetMomentum( 0.0, 0.0, pCurrent*CLHEP::GeV );
2411 pseudoParticle[1].SetMomentum( 0.0, 0.0, 0.0 );
2412 pseudoParticle[1].SetMass( targetMass*CLHEP::GeV );
2413 pseudoParticle[1].SetKineticEnergy( 0.0 );
2418 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2419 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] );
2420 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] );
2424 currentParticle.SetTotalEnergy( std::sqrt(pf*pf+currentMass*currentMass)*CLHEP::GeV );
2425 targetParticle.SetTotalEnergy( std::sqrt(pf*pf+targetMass*targetMass)*CLHEP::GeV );
2429 const G4double cb = 0.01;
2430 const G4double b1 = 4.225;
2431 const G4double b2 = 1.795;
2436 G4double
b = std::max( cb, b1+b2*std::log(pOriginal) );
2438 G4double btrang =
b * 4.0 *
pf * pseudoParticle[0].GetMomentum().mag()/CLHEP::GeV;
2440 G4double exindt = -1.0;
2441 exindt += std::exp(std::max(-btrang,expxl));
2445 G4double ctet = 1.0 + 2*std::log( 1.0+G4UniformRand()*exindt ) / btrang;
2446 if( std::fabs(ctet) > 1.0 )ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2447 G4double stet = std::sqrt( (1.0-ctet)*(1.0+ctet) );
2448 G4double
phi = CLHEP::twopi * G4UniformRand();
2453 targetParticle.GetDefinition() == aKaonMinus ||
2454 targetParticle.GetDefinition() == aKaonZeroL ||
2455 targetParticle.GetDefinition() == aKaonZeroS ||
2456 targetParticle.GetDefinition() == aKaonPlus ||
2457 targetParticle.GetDefinition() == aPiMinus ||
2458 targetParticle.GetDefinition() == aPiZero ||
2459 targetParticle.GetDefinition() == aPiPlus )
2461 currentParticle.SetMomentum( -pf*stet*std::sin(
phi)*CLHEP::GeV,
2462 -pf*stet*std::cos(
phi)*CLHEP::GeV,
2463 -pf*ctet*CLHEP::GeV );
2467 currentParticle.SetMomentum( pf*stet*std::sin(
phi)*CLHEP::GeV,
2468 pf*stet*std::cos(
phi)*CLHEP::GeV,
2469 pf*ctet*CLHEP::GeV );
2471 targetParticle.SetMomentum( currentParticle.GetMomentum() * (-1.0) );
2475 currentParticle.Lorentz( currentParticle, pseudoParticle[1] );
2476 targetParticle.Lorentz( targetParticle, pseudoParticle[1] );
2486 Defs1( modifiedOriginal, currentParticle, targetParticle,
vec, vecLen );
2488 G4double pp, pp1, ekin;
2489 if( atomicWeight >= 1.5 )
2491 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*std::exp(-(atomicWeight-1.)/120.);
2492 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
2495 ekin = currentParticle.GetKineticEnergy()/CLHEP::MeV - cfa*(1.0+0.5*normal())*CLHEP::GeV;
2496 ekin = std::max( 0.0001*CLHEP::GeV, ekin );
2497 currentParticle.SetKineticEnergy( ekin*CLHEP::MeV );
2498 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
2499 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
2501 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
2504 ekin = targetParticle.GetKineticEnergy()/CLHEP::MeV - cfa*(1.0+normal()/2.)*CLHEP::GeV;
2505 ekin = std::max( 0.0001*CLHEP::GeV, ekin );
2506 targetParticle.SetKineticEnergy( ekin*CLHEP::MeV );
2507 pp = targetParticle.GetTotalMomentum()/CLHEP::MeV;
2508 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
2513 if( atomicWeight >= 1.5 )
2525 G4double epnb, edta;
2526 G4int npnb=0, ndta=0;
2528 epnb = targetNucleus.GetPNBlackTrackEnergy();
2529 edta = targetNucleus.GetDTABlackTrackEnergy();
2530 const G4double pnCutOff = 0.0001;
2531 const G4double dtaCutOff = 0.0001;
2532 const G4double kineticMinimum = 0.0001;
2533 const G4double kineticFactor = -0.010;
2534 G4double sprob = 0.0;
2535 if( epnb >= pnCutOff )
2543 if( npnb > atomicWeight )npnb = G4int(atomicWeight);
2544 if( (epnb > pnCutOff) && (npnb <= 0) )npnb = 1;
2545 npnb = std::min( npnb, 127-vecLen );
2547 if( edta >= dtaCutOff )
2549 ndta = G4int(2.0 * std::log(atomicWeight));
2550 ndta = std::min( ndta, 127-vecLen );
2552 G4double spall = 0.0;
2571 AddBlackTrackParticles( epnb, npnb, edta, ndta, sprob, kineticMinimum, kineticFactor,
2572 modifiedOriginal, spall, targetNucleus,
2580 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
2581 currentParticle.SetTOF( 1.0-500.0*std::exp(-ekOriginal/0.04)*std::log(G4UniformRand()) );
2583 currentParticle.SetTOF( 1.0 );
2587G4double FullModelReactionDynamics::GenerateNBodyEvent(
2588 const G4double totalEnergy,
2589 const G4bool constantCrossSection,
2590 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2598 const G4double expxu = 82.;
2599 const G4double expxl = -expxu;
2602 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2603 G4cerr <<
" number of particles < 2" << G4endl;
2604 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2609 G4double pcm[3][18];
2616 G4double totalMass = 0.0;
2620 for( i=0;
i<vecLen; ++
i )
2623 vec[
i]->SetMomentum( 0.0, 0.0, 0.0 );
2628 totalMass +=
mass[
i];
2631 G4double totalE = totalEnergy/CLHEP::GeV;
2632 if( totalMass > totalE )
2645 G4double kineticEnergy = totalE - totalMass;
2649 emm[vecLen-1] = totalE;
2653 for( i=0;
i<vecLen; ++
i )ran[i] = G4UniformRand();
2654 for( i=0;
i<vecLen-2; ++
i )
2656 for( G4int j=vecLen-2;
j>
i; --
j )
2658 if( ran[i] > ran[j] )
2660 G4double temp = ran[
i];
2666 for( i=1;
i<vecLen-1; ++
i )emm[i] = ran[i-1]*kineticEnergy + sm[i];
2669 G4bool lzero =
true;
2670 G4double wtmax = 0.0;
2671 if( constantCrossSection )
2673 G4double emmax = kineticEnergy +
mass[0];
2674 G4double emmin = 0.0;
2675 for( i=1;
i<vecLen; ++
i )
2680 G4double wtfc = std::numeric_limits<G4double>::denorm_min();
2681 if( emmax*emmax > 0.0 )
2683 G4double
arg = emmax*emmax
2684 + (emmin*emmin-
mass[
i]*
mass[
i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax)
2685 - 2.0*(emmin*emmin+mass[i]*mass[i]);
2686 if( arg > 0.0 )wtfc = 0.5*std::sqrt( arg );
2689 if( wtfc <= std::numeric_limits<G4double>::denorm_min() )
2694 wtmax += std::log( wtfc );
2704 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131,
2705 256.3704, 268.4705, 240.9780, 189.2637,
2706 132.1308, 83.0202, 47.4210, 24.8295,
2707 12.0006, 5.3858, 2.2560, 0.8859 };
2708 wtmax = std::log( std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE );
2713 for( i=0;
i<vecLen-1; ++
i )
2716 pd[
i] = std::numeric_limits<G4double>::denorm_min();
2717 if( emm[i+1]*emm[i+1] > 0.0 )
2719 G4double
arg = emm[
i+1]*emm[
i+1]
2720 + (emm[
i]*emm[
i]-
mass[
i+1]*
mass[
i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1])
2721 /(emm[
i+1]*emm[
i+1])
2722 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]);
2723 if( arg > 0.0 )
pd[
i] = 0.5*std::sqrt( arg );
2726 if( pd[i] <= std::numeric_limits<G4double>::denorm_min() )
2729 wtmax += std::log( pd[i] );
2732 if( lzero )
weight = std::exp( std::max(std::min(wtmax,expxu),expxl) );
2734 G4double bang, cb,
sb,
s0,
s1,
s2,
c,
s, esys,
a,
b, gama,
beta;
2738 for( i=1;
i<vecLen; ++
i )
2741 pcm[1][
i] = -
pd[
i-1];
2743 bang = CLHEP::twopi*G4UniformRand();
2744 cb = std::cos(bang);
2745 sb = std::sin(bang);
2746 c = 2.0*G4UniformRand() - 1.0;
2747 s = std::sqrt( std::fabs( 1.0-c*c ) );
2750 esys = std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]);
2753 for( G4int j=0;
j<=
i; ++
j )
2758 energy[
j] = std::sqrt(
s0*
s0 + s1*s1 + s2*s2 + mass[j]*mass[j] );
2762 pcm[0][
j] =
a*cb -
b*
sb;
2763 pcm[2][
j] =
a*
sb +
b*cb;
2769 for( G4int j=0;
j<=
i; ++
j )
2774 energy[
j] = std::sqrt(
s0*
s0 + s1*s1 + s2*s2 + mass[j]*mass[j] );
2778 pcm[0][
j] =
a*cb -
b*
sb;
2779 pcm[2][
j] =
a*
sb +
b*cb;
2783 for( i=0;
i<vecLen; ++
i )
2785 vec[
i]->SetMomentum( pcm[0][i]*CLHEP::GeV, pcm[1][i]*CLHEP::GeV, pcm[2][i]*CLHEP::GeV );
2786 vec[
i]->SetTotalEnergy( energy[i]*CLHEP::GeV );
2800FullModelReactionDynamics::normal()
2802 G4double ran = -6.0;
2803 for( G4int i=0;
i<12; ++
i )ran += G4UniformRand();
2808FullModelReactionDynamics::Poisson( G4double
x )
2814 iran =
static_cast<G4int
>(std::max( 0.0,
x+normal()*std::sqrt(
x) ) );
2816 G4int
mm = G4int(5.0*
x);
2819 G4double
p1 =
x*std::exp(-
x);
2820 G4double
p2 =
x*
p1/2.0;
2821 G4double
p3 =
x*
p2/3.0;
2822 ran = G4UniformRand();
2835 G4double
r = std::exp(-
x);
2836 ran = G4UniformRand();
2841 for( G4int i=1;
i<=
mm; ++
i )
2845 rrr = std::exp(i*std::log(
x)-(i+0.5)*std::log((G4double)i)+i-0.9189385);
2847 rrr = std::pow(
x,i)/Factorial(i);
2849 if( ran <=
rr )
break;
2858FullModelReactionDynamics::Factorial( G4int n )
2860 G4int
m = std::min(n,10);
2862 if( m <= 1 )
return result;
2863 for( G4int i=2;
i<=
m; ++
i )result *= i;
2867void FullModelReactionDynamics::Defs1(
2868 const G4ReactionProduct &modifiedOriginal,
2869 G4ReactionProduct ¤tParticle,
2870 G4ReactionProduct &targetParticle,
2871 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2874 const G4double pjx = modifiedOriginal.GetMomentum().x()/CLHEP::MeV;
2875 const G4double pjy = modifiedOriginal.GetMomentum().y()/CLHEP::MeV;
2876 const G4double pjz = modifiedOriginal.GetMomentum().z()/CLHEP::MeV;
2877 const G4double
p = modifiedOriginal.GetMomentum().mag()/CLHEP::MeV;
2878 if( pjx*pjx+pjy*pjy > 0.0 )
2880 G4double
cost, sint, ph, cosp, sinp,
pix, piy, piz;
2882 sint = 0.5 * ( std::sqrt(std::abs((1.0-
cost)*(1.0+
cost))) + std::sqrt(pjx*pjx+pjy*pjy)/
p );
2884 ph = 3*CLHEP::halfpi;
2887 if( std::abs( pjx ) > 0.001*CLHEP::MeV )ph = std::atan2(pjy,pjx);
2888 cosp = std::cos(ph);
2889 sinp = std::sin(ph);
2890 pix = currentParticle.GetMomentum().x()/CLHEP::MeV;
2891 piy = currentParticle.GetMomentum().y()/CLHEP::MeV;
2892 piz = currentParticle.GetMomentum().z()/CLHEP::MeV;
2893 currentParticle.SetMomentum(
cost*cosp*
pix*CLHEP::MeV - sinp*piy+sint*cosp*piz*CLHEP::MeV,
2894 cost*sinp*
pix*CLHEP::MeV + cosp*piy+sint*sinp*piz*CLHEP::MeV,
2895 -sint*
pix*CLHEP::MeV +
cost*piz*CLHEP::MeV );
2896 pix = targetParticle.GetMomentum().x()/CLHEP::MeV;
2897 piy = targetParticle.GetMomentum().y()/CLHEP::MeV;
2898 piz = targetParticle.GetMomentum().z()/CLHEP::MeV;
2899 targetParticle.SetMomentum(
cost*cosp*
pix*CLHEP::MeV - sinp*piy+sint*cosp*piz*CLHEP::MeV,
2900 cost*sinp*
pix*CLHEP::MeV + cosp*piy+sint*sinp*piz*CLHEP::MeV,
2901 -sint*
pix*CLHEP::MeV +
cost*piz*CLHEP::MeV );
2902 for( G4int i=0;
i<vecLen; ++
i )
2904 pix =
vec[
i]->GetMomentum().x()/CLHEP::MeV;
2905 piy =
vec[
i]->GetMomentum().y()/CLHEP::MeV;
2906 piz =
vec[
i]->GetMomentum().z()/CLHEP::MeV;
2907 vec[
i]->SetMomentum(
cost*cosp*
pix*CLHEP::MeV - sinp*piy+sint*cosp*piz*CLHEP::MeV,
2908 cost*sinp*
pix*CLHEP::MeV + cosp*piy+sint*sinp*piz*CLHEP::MeV,
2909 -sint*
pix*CLHEP::MeV +
cost*piz*CLHEP::MeV );
2916 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() );
2917 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() );
2918 for( G4int i=0;
i<vecLen; ++
i )
2919 vec[i]->SetMomentum( -
vec[i]->GetMomentum().
z() );
2924void FullModelReactionDynamics::Rotate(
2925 const G4double numberofFinalStateNucleons,
2926 const G4ThreeVector &temp,
2927 const G4ReactionProduct &modifiedOriginal,
2928 const G4HadProjectile *originalIncident,
2929 const G4Nucleus &targetNucleus,
2930 G4ReactionProduct ¤tParticle,
2931 G4ReactionProduct &targetParticle,
2932 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
2940 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
2941 const G4double logWeight = std::log(atomicWeight);
2943 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2944 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2945 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2948 G4ThreeVector pseudoParticle[4];
2949 for( i=0;
i<4; ++
i )pseudoParticle[i].
set(0,0,0);
2950 pseudoParticle[0] = currentParticle.GetMomentum()
2951 + targetParticle.GetMomentum();
2952 for( i=0;
i<vecLen; ++
i )
2953 pseudoParticle[0] = pseudoParticle[0] + (
vec[i]->GetMomentum());
2958 G4double alekw,
p, rthnve, phinve;
2959 G4double
r1,
r2, a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2961 r1 = CLHEP::twopi*G4UniformRand();
2962 r2 = G4UniformRand();
2963 a1 = std::sqrt(-2.0*std::log(r2));
2964 ran1 = a1*std::sin(r1)*0.020*numberofFinalStateNucleons*CLHEP::GeV;
2965 ran2 = a1*std::cos(r1)*0.020*numberofFinalStateNucleons*CLHEP::GeV;
2966 G4ThreeVector Fermi(ran1, ran2, 0);
2968 pseudoParticle[0] = pseudoParticle[0]+Fermi;
2969 pseudoParticle[2] = temp;
2970 pseudoParticle[3] = pseudoParticle[0];
2972 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2973 G4double
rotation = 2.*CLHEP::pi*G4UniformRand();
2974 pseudoParticle[1] = pseudoParticle[1].rotate(rotation, pseudoParticle[3]);
2975 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2976 for(G4int ii=1; ii<=3; ii++)
2978 p = pseudoParticle[ii].mag();
2980 pseudoParticle[ii]= G4ThreeVector( 0.0, 0.0, 0.0 );
2982 pseudoParticle[ii]= pseudoParticle[ii] * (1./
p);
2985 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2986 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2987 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2988 currentParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2990 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2991 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2992 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2993 targetParticle.SetMomentum( pxTemp, pyTemp, pzTemp );
2995 for( i=0;
i<vecLen; ++
i )
2997 pxTemp = pseudoParticle[1].dot(
vec[i]->GetMomentum());
2998 pyTemp = pseudoParticle[2].dot(
vec[i]->GetMomentum());
2999 pzTemp = pseudoParticle[3].dot(
vec[i]->GetMomentum());
3000 vec[
i]->SetMomentum( pxTemp, pyTemp, pzTemp );
3006 Defs1( modifiedOriginal, currentParticle, targetParticle,
vec, vecLen );
3008 G4double dekin = 0.0;
3011 if( atomicWeight >= 1.5 )
3015 const G4double alem[] = { 1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00 };
3016 const G4double val0[] = { 0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65 };
3017 alekw = std::log( originalIncident->GetKineticEnergy()/CLHEP::GeV );
3019 if( alekw > alem[0] )
3022 for( G4int j=1;
j<7; ++
j )
3024 if( alekw < alem[j] )
3026 G4double rcnve = (val0[
j] - val0[
j-1]) / (alem[j] - alem[j-1]);
3027 exh = rcnve * alekw + val0[
j-1] - rcnve * alem[
j-1];
3033 const G4double cfa = 0.025*((atomicWeight-1.)/120.)*std::exp(-(atomicWeight-1.)/120.);
3034 ekin = currentParticle.GetKineticEnergy()/CLHEP::GeV - cfa*(1+normal()/2.0);
3035 ekin = std::max( 1.0e-6, ekin );
3041 dekin += ekin*(1.0-xxh);
3050 currentParticle.SetKineticEnergy( ekin*CLHEP::GeV );
3051 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
3052 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
3053 if( pp1 < 0.001*CLHEP::MeV )
3055 rthnve = CLHEP::pi*G4UniformRand();
3056 phinve = CLHEP::twopi*G4UniformRand();
3057 currentParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
3058 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
3059 pp*std::cos(rthnve)*CLHEP::MeV );
3062 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3063 ekin = targetParticle.GetKineticEnergy()/CLHEP::GeV - cfa*(1+normal()/2.0);
3064 ekin = std::max( 1.0e-6, ekin );
3066 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3067 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3068 (targetParticle.GetDefinition() == aPiZero) &&
3069 (G4UniformRand() < logWeight) )xxh = exh;
3070 dekin += ekin*(1.0-xxh);
3072 if( (targetParticle.GetDefinition() == aPiPlus) ||
3073 (targetParticle.GetDefinition() == aPiZero) ||
3074 (targetParticle.GetDefinition() == aPiMinus) )
3079 targetParticle.SetKineticEnergy( ekin*CLHEP::GeV );
3080 pp = targetParticle.GetTotalMomentum()/CLHEP::MeV;
3081 pp1 = targetParticle.GetMomentum().mag()/CLHEP::MeV;
3082 if( pp1 < 0.001*CLHEP::MeV )
3084 rthnve = CLHEP::pi*G4UniformRand();
3085 phinve = CLHEP::twopi*G4UniformRand();
3086 targetParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
3087 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
3088 pp*std::cos(rthnve)*CLHEP::MeV );
3091 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) );
3092 for( i=0;
i<vecLen; ++
i )
3094 ekin =
vec[
i]->GetKineticEnergy()/CLHEP::GeV - cfa*(1+normal()/2.0);
3095 ekin = std::max( 1.0e-6, ekin );
3097 if( ( (modifiedOriginal.GetDefinition() == aPiPlus) ||
3098 (modifiedOriginal.GetDefinition() == aPiMinus) ) &&
3099 (
vec[i]->GetDefinition() == aPiZero) &&
3100 (G4UniformRand() < logWeight) )xxh = exh;
3101 dekin += ekin*(1.0-xxh);
3103 if( (
vec[i]->GetDefinition() == aPiPlus) ||
3104 (
vec[i]->GetDefinition() == aPiZero) ||
3105 (
vec[i]->GetDefinition() == aPiMinus) )
3110 vec[
i]->SetKineticEnergy( ekin*CLHEP::GeV );
3111 pp =
vec[
i]->GetTotalMomentum()/CLHEP::MeV;
3112 pp1 =
vec[
i]->GetMomentum().mag()/CLHEP::MeV;
3113 if( pp1 < 0.001*CLHEP::MeV )
3115 rthnve = CLHEP::pi*G4UniformRand();
3116 phinve = CLHEP::twopi*G4UniformRand();
3117 vec[
i]->SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
3118 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
3119 pp*std::cos(rthnve)*CLHEP::MeV );
3122 vec[
i]->SetMomentum(
vec[i]->GetMomentum() * (pp/pp1) );
3125 if( (ek1 != 0.0) && (npions > 0) )
3127 dekin = 1.0 + dekin/ek1;
3131 if( (currentParticle.GetDefinition() == aPiPlus) ||
3132 (currentParticle.GetDefinition() == aPiZero) ||
3133 (currentParticle.GetDefinition() == aPiMinus) )
3135 currentParticle.SetKineticEnergy(
3136 std::max( 0.001*CLHEP::MeV, dekin*currentParticle.GetKineticEnergy() ) );
3137 pp = currentParticle.GetTotalMomentum()/CLHEP::MeV;
3138 pp1 = currentParticle.GetMomentum().mag()/CLHEP::MeV;
3141 rthnve = CLHEP::pi*G4UniformRand();
3142 phinve = CLHEP::twopi*G4UniformRand();
3143 currentParticle.SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
3144 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
3145 pp*std::cos(rthnve)*CLHEP::MeV );
3148 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) );
3169 for( i=0;
i<vecLen; ++
i )
3171 if( (
vec[i]->GetDefinition() == aPiPlus) ||
3172 (
vec[i]->GetDefinition() == aPiZero) ||
3173 (
vec[i]->GetDefinition() == aPiMinus) )
3175 vec[
i]->SetKineticEnergy( std::max( 0.001*CLHEP::MeV, dekin*
vec[i]->GetKineticEnergy() ) );
3176 pp =
vec[
i]->GetTotalMomentum()/CLHEP::MeV;
3177 pp1 =
vec[
i]->GetMomentum().mag()/CLHEP::MeV;
3180 rthnve = CLHEP::pi*G4UniformRand();
3181 phinve = CLHEP::twopi*G4UniformRand();
3183 vec[
i]->SetMomentum( pp*std::sin(rthnve)*std::cos(phinve)*CLHEP::MeV,
3184 pp*std::sin(rthnve)*std::sin(phinve)*CLHEP::MeV,
3185 pp*std::cos(rthnve)*CLHEP::MeV );
3188 vec[
i]->SetMomentum(
vec[i]->GetMomentum() * (pp/pp1) );
3194void FullModelReactionDynamics::AddBlackTrackParticles(
3195 const G4double epnb,
3197 const G4double edta,
3199 const G4double sprob,
3200 const G4double kineticMinimum,
3201 const G4double kineticFactor,
3202 const G4ReactionProduct &modifiedOriginal,
3204 const G4Nucleus &targetNucleus,
3205 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3216 G4ParticleDefinition *aProton = G4Proton::Proton();
3217 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3218 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3219 G4ParticleDefinition *aTriton = G4Triton::Triton();
3220 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3222 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/CLHEP::MeV;
3223 const G4double atomicWeight = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
3225 const G4double atomicNumber = targetNucleus.GetZ_asInt();
3228 const G4double ika1 = 3.6;
3229 const G4double ika2 = 35.56;
3230 const G4double ika3 = 6.45;
3231 const G4double sp1 = 1.066;
3237 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) * std::exp(-(atomicWeight-1.0)/120.0);
3240 G4double backwardKinetic = 0.0;
3241 G4int local_npnb = npnb;
3242 for( i=0;
i<npnb; ++
i )
if( G4UniformRand() < sprob ) local_npnb--;
3243 G4double ekin = epnb/local_npnb;
3245 for( i=0;
i<local_npnb; ++
i )
3247 G4ReactionProduct *
p1 =
new G4ReactionProduct();
3248 if( backwardKinetic > epnb )
3253 G4double ran = G4UniformRand();
3254 G4double kinetic = -ekin*std::log(ran) - cfa*(1.0+0.5*normal());
3255 if( kinetic < 0.0 )kinetic = -0.010*std::log(ran);
3256 backwardKinetic += kinetic;
3257 if( backwardKinetic > epnb )
3258 kinetic = std::max( kineticMinimum, epnb-(backwardKinetic-kinetic) );
3259 if( G4UniformRand() > (1.0-atomicNumber/atomicWeight) )
3260 p1->SetDefinition( aProton );
3262 p1->SetDefinition( aNeutron );
3263 vec.SetElement( vecLen, p1 );
3265 G4double
cost = G4UniformRand() * 2.0 - 1.0;
3266 G4double sint = std::sqrt(std::fabs(1.0-
cost*
cost));
3267 G4double
phi = CLHEP::twopi * G4UniformRand();
3268 vec[vecLen]->SetNewlyAdded(
true );
3269 vec[vecLen]->SetKineticEnergy( kinetic*CLHEP::GeV );
3271 pp =
vec[vecLen]->GetTotalMomentum()/CLHEP::MeV;
3272 vec[vecLen]->SetMomentum( pp*sint*std::sin(
phi)*CLHEP::MeV,
3273 pp*sint*std::cos(
phi)*CLHEP::MeV,
3274 pp*
cost*CLHEP::MeV );
3278 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*CLHEP::GeV) )
3280 G4double ekw = ekOriginal/CLHEP::GeV;
3282 if( ekw > 1.0 )ekw *= ekw;
3283 ekw = std::max( 0.1, ekw );
3284 ika = G4int(ika1*std::exp((atomicNumber*atomicNumber/atomicWeight-ika2)/ika3)/ekw);
3287 for( i=(vecLen-1);
i>=0; --
i )
3289 if( (
vec[i]->GetDefinition() == aProton) &&
vec[i]->GetNewlyAdded() )
3291 vec[
i]->SetDefinitionAndUpdateE( aNeutron );
3292 if( ++kk > ika )
break;
3300 G4double backwardKinetic = 0.0;
3301 G4int local_ndta=ndta;
3302 for( i=0;
i<ndta; ++
i )
if( G4UniformRand() < sprob )local_ndta--;
3303 G4double ekin = edta/local_ndta;
3305 for( i=0;
i<local_ndta; ++
i )
3307 G4ReactionProduct *
p2 =
new G4ReactionProduct();
3308 if( backwardKinetic > edta )
3313 G4double ran = G4UniformRand();
3314 G4double kinetic = -ekin*std::log(ran)-cfa*(1.+0.5*normal());
3315 if( kinetic < 0.0 )kinetic = kineticFactor*std::log(ran);
3316 backwardKinetic += kinetic;
3317 if( backwardKinetic > edta )kinetic = edta-(backwardKinetic-kinetic);
3318 if( kinetic < 0.0 )kinetic = kineticMinimum;
3319 G4double
cost = 2.0*G4UniformRand() - 1.0;
3320 G4double sint = std::sqrt(std::max(0.0,(1.0-
cost*
cost)));
3321 G4double
phi = CLHEP::twopi*G4UniformRand();
3322 ran = G4UniformRand();
3324 p2->SetDefinition( aDeuteron );
3325 else if( ran <= 0.90 )
3326 p2->SetDefinition( aTriton );
3328 p2->SetDefinition( anAlpha );
3329 spall +=
p2->GetMass()/CLHEP::GeV * sp1;
3330 if( spall > atomicWeight )
3335 vec.SetElement( vecLen, p2 );
3336 vec[vecLen]->SetNewlyAdded(
true );
3337 vec[vecLen]->SetKineticEnergy( kinetic*CLHEP::GeV );
3339 pp =
vec[vecLen]->GetTotalMomentum()/CLHEP::MeV;
3340 vec[vecLen++]->SetMomentum( pp*sint*std::sin(
phi)*CLHEP::MeV,
3341 pp*sint*std::cos(
phi)*CLHEP::MeV,
3342 pp*
cost*CLHEP::MeV );
3349void FullModelReactionDynamics::MomentumCheck(
3350 const G4ReactionProduct &modifiedOriginal,
3351 G4ReactionProduct ¤tParticle,
3352 G4ReactionProduct &targetParticle,
3353 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3356 const G4double pOriginal = modifiedOriginal.GetTotalMomentum()/CLHEP::MeV;
3357 G4double testMomentum = currentParticle.GetMomentum().mag()/CLHEP::MeV;
3359 if( testMomentum >= pOriginal )
3361 pMass = currentParticle.GetMass()/CLHEP::MeV;
3362 currentParticle.SetTotalEnergy(
3363 std::sqrt( pMass*pMass + pOriginal*pOriginal )*CLHEP::MeV );
3364 currentParticle.SetMomentum(
3365 currentParticle.GetMomentum() * (pOriginal/testMomentum) );
3367 testMomentum = targetParticle.GetMomentum().mag()/CLHEP::MeV;
3368 if( testMomentum >= pOriginal )
3370 pMass = targetParticle.GetMass()/CLHEP::MeV;
3371 targetParticle.SetTotalEnergy(
3372 std::sqrt( pMass*pMass + pOriginal*pOriginal )*CLHEP::MeV );
3373 targetParticle.SetMomentum(
3374 targetParticle.GetMomentum() * (pOriginal/testMomentum) );
3376 for( G4int i=0;
i<vecLen; ++
i )
3378 testMomentum =
vec[
i]->GetMomentum().mag()/CLHEP::MeV;
3379 if( testMomentum >= pOriginal )
3382 vec[
i]->SetTotalEnergy(
3383 std::sqrt( pMass*pMass + pOriginal*pOriginal )*CLHEP::MeV );
3384 vec[
i]->SetMomentum(
vec[i]->GetMomentum() * (pOriginal/testMomentum) );
3389void FullModelReactionDynamics::ProduceStrangeParticlePairs(
3390 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> &
vec,
3392 const G4ReactionProduct &modifiedOriginal,
3393 const G4DynamicParticle *originalTarget,
3394 G4ReactionProduct ¤tParticle,
3395 G4ReactionProduct &targetParticle,
3396 G4bool &incidentHasChanged,
3397 G4bool &targetHasChanged )
3408 if( vecLen == 0 )
return;
3412 if( currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0 )
return;
3414 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/CLHEP::GeV;
3415 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass()/CLHEP::GeV;
3416 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass()/CLHEP::GeV;
3417 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal +
3418 targetMass*targetMass +
3419 2.0*targetMass*etOriginal );
3420 G4double currentMass = currentParticle.GetMass()/CLHEP::GeV;
3421 G4double availableEnergy = centerofmassEnergy-(targetMass+currentMass);
3422 if( availableEnergy <= 1.0 )
return;
3424 G4ParticleDefinition *aProton = G4Proton::Proton();
3425 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
3426 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3427 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
3428 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
3429 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
3430 G4ParticleDefinition *aSigmaZero = G4SigmaZero::SigmaZero();
3431 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
3432 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
3433 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
3434 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
3435 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
3436 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
3437 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
3438 G4ParticleDefinition *aLambda = G4Lambda::Lambda();
3439 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
3441 const G4double protonMass = aProton->GetPDGMass()/CLHEP::GeV;
3442 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass()/CLHEP::GeV;
3446 const G4double avrs[] = {3.,4.,5.,6.,7.,8.,9.,10.,20.,30.,40.,50.};
3449 G4double avk, avy, avn, ran;
3451 while( (i<12) && (centerofmassEnergy>avrs[i]) )++
i;
3467 G4double ran = G4UniformRand();
3468 while( ran == 1.0 )ran = G4UniformRand();
3469 i4 = i3 = G4int( vecLen*ran );
3472 ran = G4UniformRand();
3473 while( ran == 1.0 )ran = G4UniformRand();
3474 i4 = G4int( vecLen*ran );
3480 const G4double avkkb[] = { 0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075,
3481 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573 };
3482 const G4double avky[] = { 0.005, 0.03, 0.064, 0.095, 0.115, 0.13,
3483 0.145, 0.155, 0.20, 0.205, 0.210, 0.212 };
3484 const G4double avnnb[] = { 0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02,
3485 0.04, 0.05, 0.12, 0.15, 0.18, 0.20 };
3487 avk = (std::log(avkkb[ibin])-std::log(avkkb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3488 /(avrs[ibin]-avrs[ibin-1]) + std::log(avkkb[ibin-1]);
3489 avk = std::exp(avk);
3491 avy = (std::log(avky[ibin])-std::log(avky[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3492 /(avrs[ibin]-avrs[ibin-1]) + std::log(avky[ibin-1]);
3493 avy = std::exp(avy);
3495 avn = (std::log(avnnb[ibin])-std::log(avnnb[ibin-1]))*(centerofmassEnergy-avrs[ibin-1])
3496 /(avrs[ibin]-avrs[ibin-1]) + std::log(avnnb[ibin-1]);
3497 avn = std::exp(avn);
3499 if( avk+avy+avn <= 0.0 )
return;
3501 if( currentMass < protonMass )avy /= 2.0;
3502 if( targetMass < protonMass )avy = 0.0;
3505 ran = G4UniformRand();
3508 if( availableEnergy < 2.0 )
return;
3511 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3512 if( G4UniformRand() < 0.5 )
3514 vec[0]->SetDefinition( aNeutron );
3515 p1->SetDefinition( anAntiNeutron );
3516 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3517 vec[0]->SetMayBeKilled(
false);
3518 p1->SetMayBeKilled(
false);
3522 vec[0]->SetDefinition( aProton );
3523 p1->SetDefinition( anAntiProton );
3524 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3525 vec[0]->SetMayBeKilled(
false);
3526 p1->SetMayBeKilled(
false);
3528 vec.SetElement( vecLen++, p1 );
3533 if( G4UniformRand() < 0.5 )
3535 vec[i3]->SetDefinition( aNeutron );
3536 vec[i4]->SetDefinition( anAntiNeutron );
3537 vec[i3]->SetMayBeKilled(
false);
3538 vec[i4]->SetMayBeKilled(
false);
3542 vec[i3]->SetDefinition( aProton );
3543 vec[i4]->SetDefinition( anAntiProton );
3544 vec[i3]->SetMayBeKilled(
false);
3545 vec[i4]->SetMayBeKilled(
false);
3549 else if( ran < avk )
3551 if( availableEnergy < 1.0 )
return;
3553 const G4double kkb[] = { 0.2500, 0.3750, 0.5000, 0.5625, 0.6250,
3554 0.6875, 0.7500, 0.8750, 1.000 };
3555 const G4int ipakkb1[] = { 10, 10, 10, 11, 11, 12, 12, 11, 12 };
3556 const G4int ipakkb2[] = { 13, 11, 12, 11, 12, 11, 12, 13, 13 };
3557 ran = G4UniformRand();
3559 while( (i<9) && (ran>=kkb[i]) )++
i;
3565 switch( ipakkb1[i] )
3568 vec[i3]->SetDefinition( aKaonPlus );
3569 vec[i3]->SetMayBeKilled(
false);
3572 vec[i3]->SetDefinition( aKaonZS );
3573 vec[i3]->SetMayBeKilled(
false);
3576 vec[i3]->SetDefinition( aKaonZL );
3577 vec[i3]->SetMayBeKilled(
false);
3582 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3583 switch( ipakkb2[i] )
3586 p1->SetDefinition( aKaonZS );
3587 p1->SetMayBeKilled(
false);
3590 p1->SetDefinition( aKaonZL );
3591 p1->SetMayBeKilled(
false);
3594 p1->SetDefinition( aKaonMinus );
3595 p1->SetMayBeKilled(
false);
3598 (G4UniformRand() < 0.5) ?
p1->SetSide( -1 ) :
p1->SetSide( 1 );
3599 vec.SetElement( vecLen++, p1 );
3604 switch( ipakkb2[i] )
3607 vec[i4]->SetDefinition( aKaonZS );
3608 vec[i4]->SetMayBeKilled(
false);
3611 vec[i4]->SetDefinition( aKaonZL );
3612 vec[i4]->SetMayBeKilled(
false);
3615 vec[i4]->SetDefinition( aKaonMinus );
3616 vec[i4]->SetMayBeKilled(
false);
3621 else if( ran < avy )
3623 if( availableEnergy < 1.6 )
return;
3625 const G4double ky[] = { 0.200, 0.300, 0.400, 0.550, 0.625, 0.700,
3626 0.800, 0.850, 0.900, 0.950, 0.975, 1.000 };
3627 const G4int ipaky1[] = { 18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22 };
3628 const G4int ipaky2[] = { 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12 };
3629 const G4int ipakyb1[] = { 19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25 };
3630 const G4int ipakyb2[] = { 13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11 };
3631 ran = G4UniformRand();
3633 while( (i<12) && (ran>ky[i]) )++
i;
3634 if( i == 12 )
return;
3635 if( (currentMass<protonMass) || (G4UniformRand()<0.5) )
3645 targetParticle.SetDefinition( aLambda );
3648 targetParticle.SetDefinition( aSigmaPlus );
3651 targetParticle.SetDefinition( aSigmaZero );
3654 targetParticle.SetDefinition( aSigmaMinus );
3657 targetHasChanged =
true;
3661 vec[i3]->SetDefinition( aKaonPlus );
3662 vec[i3]->SetMayBeKilled(
false);
3665 vec[i3]->SetDefinition( aKaonZS );
3666 vec[i3]->SetMayBeKilled(
false);
3669 vec[i3]->SetDefinition( aKaonZL );
3670 vec[i3]->SetMayBeKilled(
false);
3678 if( (currentParticle.GetDefinition() == anAntiProton) ||
3679 (currentParticle.GetDefinition() == anAntiNeutron) ||
3680 (currentParticle.GetDefinition() == anAntiLambda) ||
3681 (currentMass > sigmaMinusMass) )
3683 switch( ipakyb1[i] )
3686 currentParticle.SetDefinitionAndUpdateE( anAntiLambda );
3689 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaPlus );
3692 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaZero );
3695 currentParticle.SetDefinitionAndUpdateE( anAntiSigmaMinus );
3698 incidentHasChanged =
true;
3699 switch( ipakyb2[i] )
3702 vec[i3]->SetDefinition( aKaonZS );
3703 vec[i3]->SetMayBeKilled(
false);
3706 vec[i3]->SetDefinition( aKaonZL );
3707 vec[i3]->SetMayBeKilled(
false);
3710 vec[i3]->SetDefinition( aKaonMinus );
3711 vec[i3]->SetMayBeKilled(
false);
3720 currentParticle.SetDefinitionAndUpdateE( aLambda );
3723 currentParticle.SetDefinitionAndUpdateE( aSigmaPlus );
3726 currentParticle.SetDefinitionAndUpdateE( aSigmaZero );
3729 currentParticle.SetDefinitionAndUpdateE( aSigmaMinus );
3732 incidentHasChanged =
true;
3736 vec[i3]->SetDefinition( aKaonPlus );
3737 vec[i3]->SetMayBeKilled(
false);
3740 vec[i3]->SetDefinition( aKaonZS );
3741 vec[i3]->SetMayBeKilled(
false);
3744 vec[i3]->SetDefinition( aKaonZL );
3745 vec[i3]->SetMayBeKilled(
false);
3761 currentMass = currentParticle.GetMass()/CLHEP::GeV;
3762 targetMass = targetParticle.GetMass()/CLHEP::GeV;
3764 G4double energyCheck = centerofmassEnergy-(currentMass+targetMass);
3765 for( i=0;
i<vecLen; ++
i )
3767 energyCheck -=
vec[
i]->GetMass()/CLHEP::GeV;
3768 if( energyCheck < 0.0 )
3770 vecLen = std::max( 0, --i );
3772 for(j=i;
j<vecLen;
j++)
delete vec[j];
3780FullModelReactionDynamics::NuclearReaction(
3781 G4FastVector<G4ReactionProduct,4> &
vec,
3783 const G4HadProjectile *originalIncident,
3784 const G4Nucleus &targetNucleus,
3785 const G4double theAtomicMass,
3786 const G4double *mass )
3792 G4ParticleDefinition *aGamma = G4Gamma::Gamma();
3793 G4ParticleDefinition *aProton = G4Proton::Proton();
3794 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3795 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3796 G4ParticleDefinition *aTriton = G4Triton::Triton();
3797 G4ParticleDefinition *anAlpha = G4Alpha::Alpha();
3799 const G4double aProtonMass = aProton->GetPDGMass()/CLHEP::MeV;
3800 const G4double aNeutronMass = aNeutron->GetPDGMass()/CLHEP::MeV;
3801 const G4double aDeuteronMass = aDeuteron->GetPDGMass()/CLHEP::MeV;
3802 const G4double aTritonMass = aTriton->GetPDGMass()/CLHEP::MeV;
3803 const G4double anAlphaMass = anAlpha->GetPDGMass()/CLHEP::MeV;
3805 G4ReactionProduct currentParticle;
3806 currentParticle = *originalIncident;
3812 G4double
p = currentParticle.GetTotalMomentum();
3813 G4double pp = currentParticle.GetMomentum().mag();
3814 if( pp <= 0.001*CLHEP::MeV )
3816 G4double phinve = CLHEP::twopi*G4UniformRand();
3817 G4double rthnve = std::acos( std::max( -1.0, std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3818 currentParticle.SetMomentum( p*std::sin(rthnve)*std::cos(phinve),
3819 p*std::sin(rthnve)*std::sin(phinve),
3820 p*std::cos(rthnve) );
3823 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/pp) );
3827 G4double currentKinetic = currentParticle.GetKineticEnergy()/CLHEP::MeV;
3828 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass()/CLHEP::MeV;
3829 G4double qv = currentKinetic + theAtomicMass + currentMass;
3832 qval[0] = qv -
mass[0];
3833 qval[1] = qv -
mass[1] - aNeutronMass;
3834 qval[2] = qv -
mass[2] - aProtonMass;
3835 qval[3] = qv -
mass[3] - aDeuteronMass;
3836 qval[4] = qv -
mass[4] - aTritonMass;
3837 qval[5] = qv -
mass[5] - anAlphaMass;
3838 qval[6] = qv -
mass[6] - aNeutronMass - aNeutronMass;
3839 qval[7] = qv -
mass[7] - aNeutronMass - aProtonMass;
3840 qval[8] = qv -
mass[8] - aProtonMass - aProtonMass;
3842 if( currentParticle.GetDefinition() == aNeutron )
3845 const G4double
A = targetNucleus.AtomicMass(targetNucleus.GetA_asInt(),targetNucleus.GetZ_asInt());
3846 if( G4UniformRand() > ((
A-1.0)/230.0)*((
A-1.0)/230.0) )
3848 if( G4UniformRand() >= currentKinetic/7.9254*
A )
3849 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3856 for( i=0;
i<9; ++
i )
3858 if( mass[i] < 500.0*CLHEP::MeV )qval[
i] = 0.0;
3859 if( qval[i] < 0.0 )qval[
i] = 0.0;
3863 G4double ran = G4UniformRand();
3867 if( qval[
index] > 0.0 )
3869 qv1 += qval[
index]/qv;
3870 if( ran <= qv1 )
break;
3875 throw G4HadronicException(__FILE__, __LINE__,
3876 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3878 G4double ke = currentParticle.GetKineticEnergy()/CLHEP::GeV;
3880 if( (
index>=6) || (G4UniformRand()<std::min(0.5,ke*10.0)) )
nt = 3;
3882 G4ReactionProduct **
v =
new G4ReactionProduct * [3];
3883 v[0] =
new G4ReactionProduct;
3884 v[1] =
new G4ReactionProduct;
3885 v[2] =
new G4ReactionProduct;
3887 v[0]->SetMass( mass[
index]*CLHEP::MeV );
3891 v[1]->SetDefinition( aGamma );
3892 v[2]->SetDefinition( aGamma );
3895 v[1]->SetDefinition( aNeutron );
3896 v[2]->SetDefinition( aGamma );
3899 v[1]->SetDefinition( aProton );
3900 v[2]->SetDefinition( aGamma );
3903 v[1]->SetDefinition( aDeuteron );
3904 v[2]->SetDefinition( aGamma );
3907 v[1]->SetDefinition( aTriton );
3908 v[2]->SetDefinition( aGamma );
3911 v[1]->SetDefinition( anAlpha );
3912 v[2]->SetDefinition( aGamma );
3915 v[1]->SetDefinition( aNeutron );
3916 v[2]->SetDefinition( aNeutron );
3919 v[1]->SetDefinition( aNeutron );
3920 v[2]->SetDefinition( aProton );
3923 v[1]->SetDefinition( aProton );
3924 v[2]->SetDefinition( aProton );
3930 G4ReactionProduct pseudo1;
3931 pseudo1.SetMass( theAtomicMass*CLHEP::MeV );
3932 pseudo1.SetTotalEnergy( theAtomicMass*CLHEP::MeV );
3933 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3934 pseudo2.SetMomentum( pseudo2.GetMomentum() * (-1.0) );
3938 G4FastVector<G4ReactionProduct,MYGHADLISTSIZE> tempV;
3939 tempV.Initialize( nt );
3941 tempV.SetElement( tempLen++, v[0] );
3942 tempV.SetElement( tempLen++, v[1] );
3943 if( nt == 3 )tempV.SetElement( tempLen++, v[2] );
3944 G4bool constantCrossSection =
true;
3945 GenerateNBodyEvent( pseudo2.GetMass()/CLHEP::MeV, constantCrossSection, tempV, tempLen );
3946 v[0]->Lorentz( *v[0], pseudo2 );
3947 v[1]->Lorentz( *v[1], pseudo2 );
3948 if( nt == 3 )
v[2]->Lorentz( *v[2], pseudo2 );
3950 G4bool particleIsDefined =
false;
3951 if( v[0]->GetMass()/CLHEP::MeV - aProtonMass < 0.1 )
3953 v[0]->SetDefinition( aProton );
3954 particleIsDefined =
true;
3956 else if( v[0]->GetMass()/CLHEP::MeV - aNeutronMass < 0.1 )
3958 v[0]->SetDefinition( aNeutron );
3959 particleIsDefined =
true;
3961 else if( v[0]->GetMass()/CLHEP::MeV - aDeuteronMass < 0.1 )
3963 v[0]->SetDefinition( aDeuteron );
3964 particleIsDefined =
true;
3966 else if( v[0]->GetMass()/CLHEP::MeV - aTritonMass < 0.1 )
3968 v[0]->SetDefinition( aTriton );
3969 particleIsDefined =
true;
3971 else if( v[0]->GetMass()/CLHEP::MeV - anAlphaMass < 0.1 )
3973 v[0]->SetDefinition( anAlpha );
3974 particleIsDefined =
true;
3976 currentParticle.SetKineticEnergy(
3977 std::max( 0.001, currentParticle.GetKineticEnergy()/CLHEP::MeV ) );
3978 p = currentParticle.GetTotalMomentum();
3979 pp = currentParticle.GetMomentum().mag();
3980 if( pp <= 0.001*CLHEP::MeV )
3982 G4double phinve = CLHEP::twopi*G4UniformRand();
3983 G4double rthnve = std::acos( std::max( -1.0, std::min( 1.0, -1.0 + 2.0*G4UniformRand() ) ) );
3985 currentParticle.SetMomentum( p*std::sin(rthnve)*std::cos(phinve),
3986 p*std::sin(rthnve)*std::sin(phinve),
3987 p*std::cos(rthnve) );
3990 currentParticle.SetMomentum( currentParticle.GetMomentum() * (p/pp) );
3992 if( particleIsDefined )
3994 v[0]->SetKineticEnergy(
3995 std::max( 0.001, 0.5*G4UniformRand()*v[0]->GetKineticEnergy()/CLHEP::MeV ) );
3996 p =
v[0]->GetTotalMomentum();
3997 pp =
v[0]->GetMomentum().mag();
3998 if( pp <= 0.001*CLHEP::MeV )
4000 G4double phinve = CLHEP::twopi*G4UniformRand();
4001 G4double rthnve = std::acos( std::max(-1.0,std::min(1.0,-1.0+2.0*G4UniformRand())) );
4002 v[0]->SetMomentum( p*std::sin(rthnve)*std::cos(phinve),
4003 p*std::sin(rthnve)*std::sin(phinve),
4004 p*std::cos(rthnve) );
4007 v[0]->SetMomentum( v[0]->GetMomentum() * (p/pp) );
4009 if( (v[1]->GetDefinition() == aDeuteron) ||
4010 (v[1]->GetDefinition() == aTriton) ||
4011 (v[1]->GetDefinition() == anAlpha) )
4012 v[1]->SetKineticEnergy(
4013 std::max( 0.001, 0.5*G4UniformRand()*v[1]->GetKineticEnergy()/CLHEP::MeV ) );
4015 v[1]->SetKineticEnergy( std::max( 0.001, v[1]->GetKineticEnergy()/CLHEP::MeV ) );
4017 p =
v[1]->GetTotalMomentum();
4018 pp =
v[1]->GetMomentum().mag();
4019 if( pp <= 0.001*CLHEP::MeV )
4021 G4double phinve = CLHEP::twopi*G4UniformRand();
4022 G4double rthnve = std::acos( std::max(-1.0,std::min(1.0,-1.0+2.0*G4UniformRand())) );
4023 v[1]->SetMomentum( p*std::sin(rthnve)*std::cos(phinve),
4024 p*std::sin(rthnve)*std::sin(phinve),
4025 p*std::cos(rthnve) );
4028 v[1]->SetMomentum( v[1]->GetMomentum() * (p/pp) );
4032 if( (v[2]->GetDefinition() == aDeuteron) ||
4033 (v[2]->GetDefinition() == aTriton) ||
4034 (v[2]->GetDefinition() == anAlpha) )
4035 v[2]->SetKineticEnergy(
4036 std::max( 0.001, 0.5*G4UniformRand()*v[2]->GetKineticEnergy()/CLHEP::MeV ) );
4038 v[2]->SetKineticEnergy( std::max( 0.001, v[2]->GetKineticEnergy()/CLHEP::MeV ) );
4040 p =
v[2]->GetTotalMomentum();
4041 pp =
v[2]->GetMomentum().mag();
4042 if( pp <= 0.001*CLHEP::MeV )
4044 G4double phinve = CLHEP::twopi*G4UniformRand();
4045 G4double rthnve = std::acos( std::max(-1.0,std::min(1.0,-1.0+2.0*G4UniformRand())) );
4046 v[2]->SetMomentum( p*std::sin(rthnve)*std::cos(phinve),
4047 p*std::sin(rthnve)*std::sin(phinve),
4048 p*std::cos(rthnve) );
4051 v[2]->SetMomentum( v[2]->GetMomentum() * (p/pp) );
4054 for(del=0; del<vecLen; del++)
delete vec[del];
4056 if( particleIsDefined )
4058 vec.SetElement( vecLen++, v[0] );
4064 vec.SetElement( vecLen++, v[1] );
4067 vec.SetElement( vecLen++, v[2] );
Scalar phi() const
phi method
std::vector< size_t > vec
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
int cost(std::vector< std::string > &files, node &n, const std::string &directory="", bool deleteref=false, bool relocate=false)
std::vector< ALFA_RawDataCollection_p1 > t1
l
Printing final latex table to .tex output file.
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
hold the test vectors and ease the comparison
Extra patterns decribing particle interation process.