34#define INCLXX_IN_GEANT4_MODE 1
85 :propagationModel(0), theA(208), theZ(82), theS(0),
86 targetInitSuccess(false),
87 maxImpactParameter(0.),
88 maxUniverseRadius(0.),
89 maxInteractionDistance(0.),
90 fixedImpactParameter(0.),
93 forceTransparent(false),
97#ifdef INCLXX_IN_GEANT4_MODE
100 Logger::initialize(theConfig);
139 propagationModel =
new StandardPropagationModel(theConfig->getLocalEnergyBBType(),theConfig->getLocalEnergyPiType(),theConfig->getHadronizationTime());
144 cascadeAction->beforeRunAction(theConfig);
146 theGlobalInfo.cascadeModel = theConfig->getVersionString();
147 theGlobalInfo.deexcitationModel = theConfig->getDeExcitationString();
149 theGlobalInfo.rootSelection = theConfig->getROOTSelectionString();
152#ifndef INCLXX_IN_GEANT4_MODE
154 theGlobalInfo.At = theConfig->getTargetA();
155 theGlobalInfo.Zt = theConfig->getTargetZ();
156 theGlobalInfo.St = theConfig->getTargetS();
158 theGlobalInfo.Ap = theSpecies.
theA;
159 theGlobalInfo.Zp = theSpecies.
theZ;
160 theGlobalInfo.Sp = theSpecies.
theS;
161 theGlobalInfo.Ep = theConfig->getProjectileKineticEnergy();
162 theGlobalInfo.biasFactor = theConfig->getBias();
165 fixedImpactParameter = theConfig->getImpactParameter();
170#ifndef INCLXX_IN_GEANT4_MODE
171 NuclearMassTable::deleteTable();
179#ifndef INCLXX_IN_GEANT4_MODE
180 Logger::deleteLoggerSlave();
184 cascadeAction->afterRunAction();
185 delete cascadeAction;
186 delete propagationModel;
192 INCL_ERROR(
"Unsupported target: A = " <<
A <<
" Z = " << Z <<
" S = " <<
S <<
'\n'
193 <<
"Target configuration rejected." <<
'\n');
197 (projectileSpecies.
theZ==projectileSpecies.
theA || projectileSpecies.
theZ==0)) {
198 INCL_ERROR(
"Unsupported projectile: A = " << projectileSpecies.
theA <<
" Z = " << projectileSpecies.
theZ <<
" S = " << projectileSpecies.
theS <<
'\n'
199 <<
"Projectile configuration rejected." <<
'\n');
204 forceTransparent =
false;
207 initUniverseRadius(projectileSpecies, kineticEnergy,
A, Z);
212 G4bool ProtonIsTheVictim =
false;
213 G4bool NeutronIsTheVictim =
false;
214 G4bool DNbProtonIsTheVictim =
false;
215 G4bool DPbProtonIsTheVictim =
false;
216 theEventInfo.annihilationP =
false;
217 theEventInfo.annihilationN =
false;
221 if((projectileSpecies.
theType ==
antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.
theType ==
antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())){
229 INCL_ERROR(
"Neither antiProton nor antiNeutron annihilated");
234 if(theConfig->isNaturalTarget()){
236 neutronprob = (theA + 1 - Z)/(theA + 1 - Z + SpOverSn*Z);
240 neutronprob = (
A - Z)/(
A - Z + SpOverSn*Z);
246 if(rndm >= neutronprob){
247 theEventInfo.annihilationP =
true;
249 ProtonIsTheVictim =
true;
253 theEventInfo.annihilationN =
true;
255 NeutronIsTheVictim =
true;
257 }
else if(projectileSpecies.
theType ==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()){
260 else if(Z > 9 && Z <=30){
267 double pbarSpOverSn = 1.331;
268 double nbarSpOverSn = 1./1.331;
269 double pbarneutronprob;
270 double nbarneutronprob;
271 if(theConfig->isNaturalTarget()){
273 nbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + nbarSpOverSn*Z);
274 pbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + pbarSpOverSn*Z);
278 nbarneutronprob = (
A - Z)/(
A - Z + nbarSpOverSn*Z);
279 pbarneutronprob = (
A - Z)/(
A - Z + pbarSpOverSn*Z);
285 if (rndm >= nbarneutronprob){
286 DNbProtonIsTheVictim =
true;
287 if(rndm2 >= pbarneutronprob){
289 DPbProtonIsTheVictim =
true;
290 }
else if(rndm2 < pbarneutronprob){
293 }
else if(rndm < nbarneutronprob){
294 if(rndm2 >= pbarneutronprob){
296 DPbProtonIsTheVictim =
true;
297 }
else if(rndm2 < pbarneutronprob){
301 }
else if (!isModelA){
302 double SpOverSn = 1.331;
304 if(theConfig->isNaturalTarget()){
306 neutronprob = (theA + 1 - Z)/(theA + 1 - Z + SpOverSn*Z);
310 neutronprob = (
A - Z)/(
A - Z + SpOverSn*Z);
316 if(rndm >= neutronprob){
317 theEventInfo.annihilationP =
true;
319 ProtonIsTheVictim =
true;
322 theEventInfo.annihilationN =
true;
324 NeutronIsTheVictim =
true;
331 if(theConfig->isNaturalTarget())
338 if(ProtonIsTheVictim ==
true && NeutronIsTheVictim ==
false)
340 if(NeutronIsTheVictim ==
true && ProtonIsTheVictim ==
false)
342 if(projectileSpecies.
theType ==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && isModelA){
343 if(DNbProtonIsTheVictim ==
true && DPbProtonIsTheVictim ==
true)
345 else if(DNbProtonIsTheVictim ==
false && DPbProtonIsTheVictim ==
true)
347 else if(DNbProtonIsTheVictim ==
false && DPbProtonIsTheVictim ==
false)
349 else if(DNbProtonIsTheVictim ==
true && DPbProtonIsTheVictim ==
false)
351 }
else if (projectileSpecies.
theType ==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && !isModelA){
352 if(ProtonIsTheVictim ==
true && NeutronIsTheVictim ==
false)
354 if(NeutronIsTheVictim ==
true && ProtonIsTheVictim ==
false)
364 INCL_DEBUG(
"Maximum impact parameter initialised: " << maxImpactParameter <<
'\n');
367 initMaxInteractionDistance(projectileSpecies, kineticEnergy);
369 if((projectileSpecies.
theType ==
antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.
theType ==
antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
370 || (projectileSpecies.
theType ==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
372 if(theConfig->isNaturalTarget()){
375 G4double kineticEnergy2=kineticEnergy;
376 if (kineticEnergy2 <= 0.) kineticEnergy2=0.001;
377 theGlobalInfo.geometricCrossSection = 9.7*
378 Math::pi*std::pow((1.840 + 1.120*std::pow(currentA,(1./3.))),2)*
383 theGlobalInfo.geometricCrossSection =
388 if(projectileSpecies.
theA > 0)
389 minRemnantSize = std::min(theA, 4);
391 minRemnantSize = std::min(theA-1, 4);
405 nucleus =
new Nucleus(
A, Z,
S, theConfig, newmaxUniverseRadius, theAType);
408 nucleus =
new Nucleus(
A, Z,
S, theConfig, maxUniverseRadius, theAType);
410 nucleus->getStore()->getBook().reset();
411 nucleus->initializeParticles();
412 propagationModel->setNucleus(nucleus);
426 if (projectileSpecies.
theType==
antiProton && (targetA==1 || targetA==2) && targetZ==1 && targetS==0) {
429 preCascade_pbarH1(projectileSpecies, kineticEnergy);
431 preCascade_pbarH2(projectileSpecies, kineticEnergy);
432 theEventInfo.annihilationP =
false;
433 theEventInfo.annihilationN =
false;
439 if (rndm <= SpOverSn) {
440 theEventInfo.annihilationP =
true;
442 starlistH2.push_back(p2);
445 theEventInfo.annihilationN =
true;
447 starlistH2.push_back(p2);
453#ifdef INCLXX_IN_GEANT4_MODE
456 ed <<
" Data missing: set environment variable G4INCLDATA\n"
457 <<
" to point to the directory containing data files needed\n"
458 <<
" by the INCL++ model" <<
G4endl;
462 const G4String& dataPathppbar(dataPath0 +
"/rawppbarFS.dat");
463 const G4String& dataPathnpbar(dataPath0 +
"/rawnpbarFS.dat");
464 const G4String& dataPathppbark(dataPath0 +
"/rawppbarFSkaonic.dat");
465 const G4String& dataPathnpbark(dataPath0 +
"/rawnpbarFSkaonic.dat");
467 const G4String dataPathnbarp(dataPath0 +
"/rawnbarpFS.dat");
468 const G4String dataPathnbarn(dataPath0 +
"/rawnbarnFS.dat");
471 if (theConfig) path = theConfig->getINCLXXDataFilePath();
472 const std::string& dataPathppbar(path +
"/rawppbarFS.dat");
473 INCL_DEBUG(
"Reading https://doi.org/10.1016/0375-9474(92)90362-N ppbar final states" << dataPathppbar <<
'\n');
474 const std::string& dataPathnpbar(path +
"/rawnpbarFS.dat");
475 INCL_DEBUG(
"Reading https://doi.org/10.1016/0375-9474(92)90362-N npbar final states" << dataPathnpbar <<
'\n');
476 const std::string& dataPathppbark(path +
"/rawppbarFSkaonic.dat");
477 INCL_DEBUG(
"Reading https://doi.org/10.1016/j.physrep.2005.03.002 ppbar kaonic final states" << dataPathppbark <<
'\n');
478 const std::string& dataPathnpbark(path +
"/rawnpbarFSkaonic.dat");
479 INCL_DEBUG(
"Reading https://doi.org/10.1007/BF02818764 and https://link.springer.com/article/10.1007/BF02754930 npbar kaonic final states" << dataPathnpbark <<
'\n');
481 const std::string& dataPathnbarp(path +
"/rawnnbarpFS.dat ");
482 INCL_DEBUG(
"Reading nbarp final states" << dataPathnbarp <<
'\n');
483 const std::string& dataPathnbarpk(path +
"/rawnbarpFSkaonic.dat");
484 INCL_DEBUG(
"Reading nbarp kaonic final states");
485 const std::string& dataPathnbarn(path +
"/rawnbarnFS.dat");
486 INCL_DEBUG(
"Reading nbarn final states" << dataPathnbarn <<
'\n');
490 std::vector<G4double> probabilities;
491 std::vector<std::vector<G4String>> particle_types;
500 if (rdm < (1.-kaonicFSprob)) {
501 INCL_DEBUG(
"pionic pp final state chosen" <<
'\n');
502 if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
503 {sum = read_file(dataPathppbar, probabilities, particle_types);}
505 {sum = read_file(dataPathnpbar, probabilities, particle_types);}
506 rdm = (rdm/(1.-kaonicFSprob))*sum;
508 G4int n = findStringNumber(rdm, std::move(probabilities))-1;
509 if ( n < 0 )
return theEventInfo;
510 for (
G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++) {
511 if (particle_types[n][j] ==
"pi0") {
513 starlist.push_back(p);
514 }
else if (particle_types[n][j] ==
"pi-") {
516 starlist.push_back(p);
517 }
else if (particle_types[n][j] ==
"pi+") {
519 starlist.push_back(p);
520 }
else if (particle_types[n][j] ==
"omega") {
522 starlist.push_back(p);
523 }
else if (particle_types[n][j] ==
"eta") {
525 starlist.push_back(p);
526 }
else if (particle_types[n][j] ==
"rho-") {
528 starlist.push_back(p);
530 starlist.push_back(pp);
531 }
else if (particle_types[n][j] ==
"rho+") {
533 starlist.push_back(p);
535 starlist.push_back(pp);
536 }
else if (particle_types[n][j] ==
"rho0") {
538 starlist.push_back(p);
540 starlist.push_back(pp);
542 INCL_ERROR(
"Some non-existing FS particle detected when reading pbar FS files");
543 for (
G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++) {
544#ifdef INCLXX_IN_GEANT4_MODE
545 G4cout <<
"gotcha! " << particle_types[n][jj] <<
G4endl;
547 std::cout <<
"gotcha! " << particle_types[n][jj] << std::endl;
550#ifdef INCLXX_IN_GEANT4_MODE
551 G4cout <<
"Some non-existing FS particle detected when reading pbar FS files" <<
G4endl;
553 std::cout <<
"Some non-existing FS particle detected when reading pbar FS files" << std::endl;
558 INCL_DEBUG(
"kaonic pp final state chosen" <<
'\n');
559 if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
560 {sum = read_file(dataPathppbark, probabilities, particle_types);}
562 {sum = read_file(dataPathnpbark, probabilities, particle_types);}
563 rdm = ((1.-rdm)/kaonicFSprob)*sum;
565 G4int n = findStringNumber(rdm, std::move(probabilities))-1;
566 if ( n < 0 )
return theEventInfo;
567 for (
G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++) {
568 if (particle_types[n][j] ==
"pi0") {
570 starlist.push_back(p);
571 }
else if (particle_types[n][j] ==
"pi-") {
573 starlist.push_back(p);
574 }
else if (particle_types[n][j] ==
"pi+") {
576 starlist.push_back(p);
577 }
else if (particle_types[n][j] ==
"omega") {
579 starlist.push_back(p);
580 }
else if (particle_types[n][j] ==
"eta") {
582 starlist.push_back(p);
583 }
else if (particle_types[n][j] ==
"K-") {
585 starlist.push_back(p);
586 }
else if (particle_types[n][j] ==
"K+") {
588 starlist.push_back(p);
589 }
else if (particle_types[n][j] ==
"K0") {
591 starlist.push_back(p);
592 }
else if (particle_types[n][j] ==
"K0b") {
594 starlist.push_back(p);
596 INCL_ERROR(
"Some non-existing FS particle detected when reading pbar FS files");
597 for (
G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++) {
598#ifdef INCLXX_IN_GEANT4_MODE
599 G4cout <<
"gotcha! " << particle_types[n][jj] <<
G4endl;
601 std::cout <<
"gotcha! " << particle_types[n][jj] << std::endl;
604#ifdef INCLXX_IN_GEANT4_MODE
605 G4cout <<
"Some non-existing FS particle detected when reading pbar FS files" <<
G4endl;
607 std::cout <<
"Some non-existing FS particle detected when reading pbar FS files" << std::endl;
615 if (starlist.size() < 2) {
616 INCL_ERROR(
"should never happen, at least 2 final state particles!" <<
'\n');
617 }
else if (starlist.size() == 2) {
622 G4double s = energyOfMesonStar*energyOfMesonStar;
623 G4double mom1 = std::sqrt(s/4. - (std::pow(m1,2) + std::pow(m2,2))/2. - std::pow(m1,2)*std::pow(m2,2)/s + (std::pow(m1,4) + 2.*std::pow(m1*m2,2) + std::pow(m2,4))/(4.*s));
625 (*first)->setMomentum(momentello);
626 (*first)->adjustEnergyFromMomentum();
627 (*last)->setMomentum(-momentello);
628 (*last)->adjustEnergyFromMomentum();
633 if (targetA==1) postCascade_pbarH1(starlist);
634 else postCascade_pbarH2(starlist,starlistH2);
636 theGlobalInfo.nShots++;
640 if ((projectileSpecies.
theType==
antiNeutron)&& (targetA==1 || targetA==2) && targetZ==1 && targetS==0) {
643 preCascade_nbarH1(projectileSpecies, kineticEnergy);
645 preCascade_nbarH2(projectileSpecies, kineticEnergy);
646 theEventInfo.annihilationP =
false;
647 theEventInfo.annihilationN =
false;
653 if (rndm <= SpOverSn) {
654 theEventInfo.annihilationP =
true;
656 starlistH2.push_back(p2);
659 theEventInfo.annihilationN =
true;
661 starlistH2.push_back(p2);
667#ifdef INCLXX_IN_GEANT4_MODE
670 ed <<
" Data missing: set environment variable G4INCLDATA\n"
671 <<
" to point to the directory containing data files needed\n"
672 <<
" by the INCL++ model" <<
G4endl;
676 G4String dataPathnbarp(dataPath0 +
"/rawnbarpFS.dat");
677 G4String dataPathnbarn(dataPath0 +
"/rawnbarnFS.dat");
678 G4String dataPathnbarnk(dataPath0 +
"/rawppbarFSkaonic.dat");
679 G4String dataPathnbarpk(dataPath0 +
"/rawnbarpFSkaonic.dat");
682 if (theConfig) path = theConfig->getINCLXXDataFilePath();
683 std::string dataPathnbarn(path +
"/rawnbarnFS.dat");
684 INCL_DEBUG(
"Reading nbarn final states" << dataPathnbarn <<
'\n');
685 std::string dataPathnbarp(path +
"/rawnbarpFS.dat");
686 INCL_DEBUG(
"Reading nbarp final states" << dataPathnbarp <<
'\n');
687 std::string dataPathnbarnk(path +
"/rawppbarFSkaonic.dat");
688 INCL_DEBUG(
"Reading nbarn kaonic final states" << dataPathnbarnk <<
'\n');
689 std::string dataPathnbarpk(path +
"/rawnbarpFSkaonic.dat");
690 INCL_DEBUG(
"Reading nbarp kaonic final states" << dataPathnbarpk <<
'\n');
693 std::vector<double> probabilities;
694 std::vector<std::vector<G4String>> particle_types;
696 double kaonicFSprob=0.05;
703 if (rdm < (1.-kaonicFSprob)) {
704 INCL_DEBUG(
"pionic nn final state chosen" <<
'\n');
705 if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
706 {sum = read_file(dataPathnbarp, probabilities, particle_types);}
708 {sum = read_file(dataPathnbarn, probabilities, particle_types);}
709 rdm = (rdm/(1.-kaonicFSprob))*sum;
711 G4int n = findStringNumber(rdm, probabilities)-1;
712 if ( n < 0 )
return theEventInfo;
713 for (
G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
714 if (particle_types[n][j] ==
"pi0") {
716 starlist.push_back(p);
717 }
else if (particle_types[n][j] ==
"pi-") {
719 starlist.push_back(p);
720 }
else if (particle_types[n][j] ==
"pi+") {
722 starlist.push_back(p);
723 }
else if (particle_types[n][j] ==
"omega") {
725 starlist.push_back(p);
726 }
else if (particle_types[n][j] ==
"eta") {
728 starlist.push_back(p);
729 }
else if (particle_types[n][j] ==
"rho-") {
731 starlist.push_back(p);
733 starlist.push_back(pp);
734 }
else if (particle_types[n][j] ==
"rho+") {
736 starlist.push_back(p);
738 starlist.push_back(pp);
739 }
else if (particle_types[n][j] ==
"rho0") {
741 starlist.push_back(p);
743 starlist.push_back(pp);
745 INCL_ERROR(
"Some non-existing FS particle detected when reading pbar FS files");
746 for (
int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
747#ifdef INCLXX_IN_GEANT4_MODE
748 G4cout <<
"gotcha! " << particle_types[n][jj] <<
G4endl;
750 std::cout <<
"gotcha! " << particle_types[n][jj] << std::endl;
753#ifdef INCLXX_IN_GEANT4_MODE
754 G4cout <<
"Some non-existing FS particle detected when reading pbar FS files" <<
G4endl;
756 std::cout <<
"Some non-existing FS particle detected when reading pbar FS files" << std::endl;
761 INCL_DEBUG(
"kaonic pp final state chosen" <<
'\n');
762 if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
763 {sum = read_file(dataPathnbarpk, probabilities, particle_types);}
765 {sum = read_file(dataPathnbarnk, probabilities, particle_types);}
766 rdm = ((1.-rdm)/kaonicFSprob)*sum;
768 G4int n = findStringNumber(rdm, probabilities)-1;
769 if ( n < 0 )
return theEventInfo;
770 for (
G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
771 if (particle_types[n][j] ==
"pi0") {
773 starlist.push_back(p);
774 }
else if (particle_types[n][j] ==
"pi-") {
776 starlist.push_back(p);
777 }
else if (particle_types[n][j] ==
"pi+") {
779 starlist.push_back(p);
780 }
else if (particle_types[n][j] ==
"omega") {
782 starlist.push_back(p);
783 }
else if (particle_types[n][j] ==
"eta") {
785 starlist.push_back(p);
786 }
else if (particle_types[n][j] ==
"K-") {
788 starlist.push_back(p);
789 }
else if (particle_types[n][j] ==
"K+") {
791 starlist.push_back(p);
792 }
else if (particle_types[n][j] ==
"K0") {
794 starlist.push_back(p);
795 }
else if (particle_types[n][j] ==
"K0b") {
797 starlist.push_back(p);
799 INCL_ERROR(
"Some non-existing FS particle detected when reading pbar FS files");
800 for (
int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
801#ifdef INCLXX_IN_GEANT4_MODE
802 G4cout <<
"gotcha! " << particle_types[n][jj] <<
G4endl;
804 std::cout <<
"gotcha! " << particle_types[n][jj] << std::endl;
807#ifdef INCLXX_IN_GEANT4_MODE
808 G4cout <<
"Some non-existing FS particle detected when reading pbar FS files" <<
G4endl;
810 std::cout <<
"Some non-existing FS particle detected when reading pbar FS files" << std::endl;
818 if (starlist.size() < 2) {
819 INCL_ERROR(
"should never happen, at least 2 final state particles!" <<
'\n');
820 }
else if (starlist.size() == 2) {
825 G4double s = energyOfMesonStar*energyOfMesonStar;
826 G4double mom1 = std::sqrt(s/4. - (std::pow(m1,2) + std::pow(m2,2))/2. - std::pow(m1,2)*std::pow(m2,2)/s + (std::pow(m1,4) + 2.*std::pow(m1*m2,2) + std::pow(m2,4))/(4.*s));
828 (*first)->setMomentum(momentello);
829 (*first)->adjustEnergyFromMomentum();
830 (*last)->setMomentum(-momentello);
831 (*last)->adjustEnergyFromMomentum();
836 if (targetA==1) postCascade_pbarH1(starlist);
837 else postCascade_pbarH2(starlist,starlistH2);
839 theGlobalInfo.nShots++;
849 targetInitSuccess =
prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ, targetS);
851 if(!targetInitSuccess) {
852 INCL_WARN(
"Target initialisation failed for A=" << targetA <<
", Z=" << targetZ <<
", S=" << targetS <<
'\n');
853 theEventInfo.transparent=
true;
857 cascadeAction->beforeCascadeAction(propagationModel);
859 const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
862 postCascade(projectileSpecies, kineticEnergy);
863 cascadeAction->afterCascadeAction(nucleus);
871 theEventInfo.
reset();
879 theEventInfo.
Sp = (
Short_t)projectileSpecies.theS;
880 theEventInfo.
Ep = kineticEnergy;
894 theEventInfo.annihilationN =
true;
895 theEventInfo.At = (
Short_t)nucleus->getA()+2;
896 theEventInfo.Zt = (
Short_t)nucleus->getZ();
899 theEventInfo.annihilationP =
true;
900 theEventInfo.At = (
Short_t)nucleus->getA()+2;
901 theEventInfo.Zt = (
Short_t)nucleus->getZ()+2;
904 theEventInfo.annihilationN =
true;
905 theEventInfo.annihilationP =
true;
906 theEventInfo.At = (
Short_t)nucleus->getA()+2;
907 theEventInfo.Zt = (
Short_t)nucleus->getZ()+1;
910 theEventInfo.At = (
Short_t)nucleus->getA();
911 theEventInfo.Zt = (
Short_t)nucleus->getZ();
914 if(maxImpactParameter<=0.) {
918 if((projectileSpecies.theType ==
antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType==
antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
919 || (projectileSpecies.theType ==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){
923 theEventInfo.transparent =
true;
932 if(fixedImpactParameter<0.) {
933 impactParameter = maxImpactParameter * std::sqrt(
Random::shoot0());
936 impactParameter = fixedImpactParameter;
939 INCL_DEBUG(
"Selected impact parameter: " << impactParameter <<
'\n');
942 theEventInfo.impactParameter = impactParameter;
944 const G4double effectiveImpactParameter = propagationModel->shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
945 if(effectiveImpactParameter < 0.) {
947 theEventInfo.transparent =
true;
952 theEventInfo.transparent =
false;
953 theEventInfo.effectiveImpactParameter = effectiveImpactParameter;
958 void INCL::cascade() {
959 FinalState *finalState =
new FinalState;
961 unsigned long loopCounter = 0;
962 const unsigned long maxLoopCounter = 10000000;
965 cascadeAction->beforePropagationAction(propagationModel);
969 IAvatar *avatar = propagationModel->propagate(finalState);
974 cascadeAction->afterPropagationAction(propagationModel, avatar);
976 if(avatar == 0)
break;
979 cascadeAction->beforeAvatarAction(avatar, nucleus);
988 avatar->fillFinalState(finalState);
990 cascadeAction->afterAvatarAction(avatar, nucleus, finalState);
993 nucleus->applyFinalState(finalState);
999 }
while(continueCascade() && loopCounter<maxLoopCounter);
1006 theEventInfo.stoppingTime = propagationModel->getCurrentTime();
1012 if(!(projectileSpecies.theType==
antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType ==
antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
1013 && !(projectileSpecies.theType==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
1014 if(nucleus->getTryCompoundNucleus()) {
1015 INCL_DEBUG(
"Trying compound nucleus" <<
'\n');
1016 makeCompoundNucleus();
1017 theEventInfo.transparent = forceTransparent;
1019#ifndef INCLXX_IN_GEANT4_MODE
1020 if(!theEventInfo.transparent) globalConservationChecks(
true);
1026 if(!(projectileSpecies.theType==
antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType ==
antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
1027 && !(projectileSpecies.theType==
antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){
1028 theEventInfo.transparent = forceTransparent || nucleus->isEventTransparent();
1031 if(theEventInfo.transparent) {
1032 ProjectileRemnant *
const projectileRemnant = nucleus->getProjectileRemnant();
1033 if(projectileRemnant) {
1035 nucleus->getStore()->clearIncoming();
1038 nucleus->getStore()->deleteIncoming();
1042 theEventInfo.antinucleonsInside = nucleus->containsAntinucleon();
1044 if(nucleus->containsAntinucleon())
1045 theEventInfo.emitAntinucleon = nucleus->emitInsideAnnihilationProducts();
1046 if(nucleus->containsAntilambda())
1047 theEventInfo.emitAntilambda = nucleus->emitInsideAntilambda();
1050 theEventInfo.sigmasInside = nucleus->containsSigma();
1051 theEventInfo.antikaonsInside = nucleus->containsAntiKaon();
1052 theEventInfo.lambdasInside = nucleus->containsLambda();
1053 theEventInfo.kaonsInside = nucleus->containsKaon();
1056 theEventInfo.absorbedStrangeParticle = nucleus->decayInsideStrangeParticles();
1059 nucleus->emitInsideStrangeParticles();
1060 theEventInfo.emitKaon = nucleus->emitInsideKaon();
1062#ifdef INCLXX_IN_GEANT4_MODE
1063 theEventInfo.emitLambda = nucleus->emitInsideLambda();
1067 theEventInfo.deltasInside = nucleus->containsDeltas();
1070 theEventInfo.forcedDeltasOutside = nucleus->decayOutgoingDeltas();
1071 theEventInfo.forcedDeltasInside = nucleus->decayInsideDeltas();
1074 G4double timeThreshold=theConfig->getDecayTimeThreshold();
1075 theEventInfo.forcedPionResonancesOutside = nucleus->decayOutgoingPionResonances(timeThreshold);
1076 nucleus->decayOutgoingSigmaZero(timeThreshold);
1077 nucleus->decayOutgoingNeutralKaon();
1088 if(nucleus->getStore()->getOutgoingParticles().size()==0
1089 && (!nucleus->getProjectileRemnant()
1090 || nucleus->getProjectileRemnant()->getParticles().size()==0)) {
1092 INCL_DEBUG(
"Cascade resulted in complete fusion, using realistic fusion kinematics" <<
'\n');
1094 nucleus->useFusionKinematics();
1096 if(nucleus->getExcitationEnergy()<0.) {
1098 INCL_WARN(
"Complete-fusion kinematics yields negative excitation energy, returning a transparent!" <<
'\n');
1099 theEventInfo.transparent =
true;
1106 nucleus->setExcitationEnergy(nucleus->computeExcitationEnergy());
1110 theEventInfo.nUnmergedSpectators = makeProjectileRemnant();
1113 if(nucleus->getA()==1 && minRemnantSize>1) {
1114 INCL_ERROR(
"Computing one-nucleon recoil kinematics. We should never be here nowadays, cascade should stop earlier than this." <<
'\n');
1116 nucleus->computeRecoilKinematics();
1118#ifndef INCLXX_IN_GEANT4_MODE
1120 globalConservationChecks(
false);
1125 if(nucleus->hasRemnant()) rescaleOutgoingForRecoil();
1130 theEventInfo.clusterDecay = nucleus->decayOutgoingClusters() || nucleus->decayMe();
1132#ifndef INCLXX_IN_GEANT4_MODE
1134 globalConservationChecks(
true);
1138 nucleus->fillEventInfo(&theEventInfo);
1143 void INCL::makeCompoundNucleus() {
1149 if(!nucleus->isNucleusNucleusCollision()) {
1150 forceTransparent =
true;
1155 nucleus->getStore()->clearIncoming();
1156 nucleus->getStore()->clearOutgoing();
1157 nucleus->getProjectileRemnant()->reset();
1158 nucleus->setA(theEventInfo.At);
1159 nucleus->setZ(theEventInfo.Zt);
1164 ThreeVector theCNMomentum = nucleus->getIncomingMomentum();
1165 ThreeVector theCNSpin = nucleus->getIncomingAngularMomentum();
1167 G4int theCNA=theEventInfo.At, theCNZ=theEventInfo.Zt, theCNS=theEventInfo.St;
1168 Cluster *
const theProjectileRemnant = nucleus->getProjectileRemnant();
1169 G4double theCNEnergy = theTargetMass + theProjectileRemnant->getEnergy();
1172 ParticleList const &initialProjectileComponents = theProjectileRemnant->getParticles();
1173 std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
1175 std::shuffle(shuffledComponents.begin(), shuffledComponents.end(),
Random::getAdapter());
1178 G4bool atLeastOneNucleonEntering =
false;
1179 for(std::vector<Particle*>::const_iterator p=shuffledComponents.begin(), e=shuffledComponents.end(); p!=e; ++p) {
1182 (*p)->getPosition(),
1183 (*p)->getPropagationVelocity(),
1184 maxInteractionDistance));
1185 if(!intersectionInteractionDistance.exists)
1189 atLeastOneNucleonEntering =
true;
1190 ParticleEntryAvatar *theAvatar =
new ParticleEntryAvatar(0.0, nucleus, *p);
1191 nucleus->getStore()->addParticleEntryAvatar(theAvatar);
1192 FinalState *fs = theAvatar->getFinalState();
1193 nucleus->applyFinalState(fs);
1202 theCNZ += (*p)->getZ();
1203 theCNS += (*p)->getS();
1213 if(!success || !atLeastOneNucleonEntering) {
1214 INCL_DEBUG(
"No nucleon entering in forced CN, forcing a transparent" <<
'\n');
1215 forceTransparent =
true;
1225 theCNEnergy -= theProjectileRemnant->getEnergy();
1226 theCNMomentum -= theProjectileRemnant->getMomentum();
1229 nucleus->finalizeProjectileRemnant(propagationModel->getCurrentTime());
1233 theCNSpin -= theProjectileRemnant->getAngularMomentum();
1237 const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
1238 if(theCNInvariantMassSquared<0.) {
1240 forceTransparent =
true;
1243 const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
1244 if(theCNExcitationEnergy<0.) {
1246 INCL_DEBUG(
"CN excitation energy is negative, forcing a transparent" <<
'\n'
1247 <<
" theCNA = " << theCNA <<
'\n'
1248 <<
" theCNZ = " << theCNZ <<
'\n'
1249 <<
" theCNS = " << theCNS <<
'\n'
1250 <<
" theCNEnergy = " << theCNEnergy <<
'\n'
1251 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" <<
'\n'
1252 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy <<
'\n'
1253 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" <<
'\n'
1255 forceTransparent =
true;
1259 INCL_DEBUG(
"CN excitation energy is positive, forcing a CN" <<
'\n'
1260 <<
" theCNA = " << theCNA <<
'\n'
1261 <<
" theCNZ = " << theCNZ <<
'\n'
1262 <<
" theCNS = " << theCNS <<
'\n'
1263 <<
" theCNEnergy = " << theCNEnergy <<
'\n'
1264 <<
" theCNMomentum = (" << theCNMomentum.getX() <<
", "<< theCNMomentum.getY() <<
", " << theCNMomentum.getZ() <<
")" <<
'\n'
1265 <<
" theCNExcitationEnergy = " << theCNExcitationEnergy <<
'\n'
1266 <<
" theCNSpin = (" << theCNSpin.getX() <<
", "<< theCNSpin.getY() <<
", " << theCNSpin.getZ() <<
")" <<
'\n'
1268 nucleus->setA(theCNA);
1269 nucleus->setZ(theCNZ);
1270 nucleus->setS(theCNS);
1271 nucleus->setMomentum(theCNMomentum);
1272 nucleus->setEnergy(theCNEnergy);
1273 nucleus->setExcitationEnergy(theCNExcitationEnergy);
1274 nucleus->setMass(theCNMass+theCNExcitationEnergy);
1275 nucleus->setSpin(theCNSpin);
1278 theEventInfo.forcedDeltasOutside = nucleus->decayOutgoingDeltas();
1281 G4double timeThreshold=theConfig->getDecayTimeThreshold();
1282 theEventInfo.forcedPionResonancesOutside = nucleus->decayOutgoingPionResonances(timeThreshold);
1285 theEventInfo.emitKaon = nucleus->emitInsideKaon();
1288 theEventInfo.clusterDecay = nucleus->decayOutgoingClusters() || nucleus->decayMe();
1291 nucleus->fillEventInfo(&theEventInfo);
1295 void INCL::rescaleOutgoingForRecoil() {
1296 RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
1299 const RootFinder::Solution theSolution =
RootFinder::solve(&theRecoilFunctor, 1.0);
1300 if(theSolution.success) {
1301 theRecoilFunctor(theSolution.x);
1303 INCL_WARN(
"Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." <<
'\n');
1307#ifndef INCLXX_IN_GEANT4_MODE
1308 void INCL::globalConservationChecks(
G4bool afterRecoil) {
1309 Nucleus::ConservationBalance theBalance = nucleus->getConservationBalance(theEventInfo,afterRecoil);
1312 const G4double pLongBalance = theBalance.momentum.getZ();
1313 const G4double pTransBalance = theBalance.momentum.perp();
1314 if(theBalance.Z != 0) {
1315 INCL_ERROR(
"Violation of charge conservation! ZBalance = " << theBalance.Z <<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1317 if(theBalance.A != 0) {
1318 INCL_ERROR(
"Violation of baryon-number conservation! ABalance = " << theBalance.A <<
" Emit Lambda=" << theEventInfo.emitLambda <<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1320 if(theBalance.S != 0) {
1321 INCL_ERROR(
"Violation of strange-number conservation! SBalance = " << theBalance.S <<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1323 G4double EThreshold, pLongThreshold, pTransThreshold;
1327 pLongThreshold = 1.;
1328 pTransThreshold = 1.;
1332 pLongThreshold = 0.1;
1333 pTransThreshold = 0.1;
1335 if(std::abs(theBalance.energy)>EThreshold) {
1336 INCL_WARN(
"Violation of energy conservation > " << EThreshold <<
" MeV. EBalance = " << theBalance.energy <<
" Emit Lambda=" << theEventInfo.emitLambda <<
" afterRecoil = " << afterRecoil <<
" SRCevent ="
1337 << nucleus->getStore()->getBook().getAcceptedSrcCollisions()<<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1339 if(std::abs(pLongBalance)>pLongThreshold) {
1340 INCL_WARN(
"Violation of longitudinal momentum conservation > " << pLongThreshold <<
" MeV/c. pLongBalance = " << pLongBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1342 if(std::abs(pTransBalance)>pTransThreshold) {
1343 INCL_WARN(
"Violation of transverse momentum conservation > " << pTransThreshold <<
" MeV/c. pTransBalance = " << pTransBalance <<
" afterRecoil = " << afterRecoil <<
" eventNumber=" << theEventInfo.eventNumber <<
'\n');
1347 theEventInfo.EBalance = theBalance.energy;
1348 theEventInfo.pLongBalance = pLongBalance;
1349 theEventInfo.pTransBalance = pTransBalance;
1353 G4bool INCL::continueCascade() {
1355 if(propagationModel->getCurrentTime() > propagationModel->getStoppingTime()) {
1356 INCL_DEBUG(
"Cascade time (" << propagationModel->getCurrentTime()
1357 <<
") exceeded stopping time (" << propagationModel->getStoppingTime()
1358 <<
"), stopping cascade" <<
'\n');
1362 if(nucleus->getStore()->getBook().getCascading()==0 &&
1363 nucleus->getStore()->getIncomingParticles().empty()) {
1364 INCL_DEBUG(
"No participants in the nucleus and no incoming particles left, stopping cascade" <<
'\n');
1368 if(nucleus->getA() <= minRemnantSize) {
1369 INCL_DEBUG(
"Remnant size (" << nucleus->getA()
1370 <<
") smaller than or equal to minimum (" << minRemnantSize
1371 <<
"), stopping cascade" <<
'\n');
1374 if((nucleus->getZ() <= 2) && (propagationModel->getCurrentTime() != 0)) {
1375 INCL_DEBUG(
"Remnant size (" << nucleus->getZ()
1376 <<
") smaller than or equal to minimum (" <<
"2"
1377 <<
"), stopping cascade" <<
'\n');
1382 if(nucleus->getTryCompoundNucleus()) {
1383 INCL_DEBUG(
"Trying to make a compound nucleus, stopping cascade" <<
'\n');
1391 const G4double normalisationFactor = theGlobalInfo.geometricCrossSection /
1393 theGlobalInfo.nucleonAbsorptionCrossSection = normalisationFactor *
1394 ((
G4double) theGlobalInfo.nNucleonAbsorptions);
1395 theGlobalInfo.pionAbsorptionCrossSection = normalisationFactor *
1396 ((
G4double) theGlobalInfo.nPionAbsorptions);
1397 theGlobalInfo.reactionCrossSection = normalisationFactor *
1398 ((
G4double) (theGlobalInfo.nShots - theGlobalInfo.nTransparents));
1399 theGlobalInfo.errorReactionCrossSection = normalisationFactor *
1400 std::sqrt((
G4double) (theGlobalInfo.nShots - theGlobalInfo.nTransparents));
1401 theGlobalInfo.forcedCNCrossSection = normalisationFactor *
1402 ((
G4double) theGlobalInfo.nForcedCompoundNucleus);
1403 theGlobalInfo.errorForcedCNCrossSection = normalisationFactor *
1404 std::sqrt((
G4double) (theGlobalInfo.nForcedCompoundNucleus));
1405 theGlobalInfo.completeFusionCrossSection = normalisationFactor *
1406 ((
G4double) theGlobalInfo.nCompleteFusion);
1407 theGlobalInfo.errorCompleteFusionCrossSection = normalisationFactor *
1408 std::sqrt((
G4double) (theGlobalInfo.nCompleteFusion));
1409 theGlobalInfo.energyViolationInteractionCrossSection = normalisationFactor *
1410 ((
G4double) theGlobalInfo.nEnergyViolationInteraction);
1412 theGlobalInfo.initialRandomSeeds.assign(initialSeeds.begin(), initialSeeds.end());
1415 theGlobalInfo.finalRandomSeeds.assign(theSeeds.begin(), theSeeds.end());
1418 G4int INCL::makeProjectileRemnant() {
1427 G4int nUnmergedSpectators = 0;
1430 if(dynSpectators.empty() && geomSpectators.empty()) {
1432 }
else if(dynSpectators.size()==1 && geomSpectators.empty()) {
1438 ProjectileRemnant *theProjectileRemnant = nucleus->getProjectileRemnant();
1441 ParticleList rejected = theProjectileRemnant->addAllDynamicalSpectators(dynSpectators);
1443 nUnmergedSpectators = (
G4int)rejected.size();
1444 nucleus->getStore()->addToOutgoing(rejected);
1447 nucleus->finalizeProjectileRemnant(propagationModel->getCurrentTime());
1451 return nUnmergedSpectators;
1454 void INCL::initMaxInteractionDistance(
ParticleSpecies const &projectileSpecies,
const G4double kineticEnergy) {
1456 maxInteractionDistance = 0.;
1462 if (projectileSpecies.theType ==
Composite){
1465 maxInteractionDistance = r0 + theNNDistance;
1466 INCL_DEBUG(
"Initialised interaction distance: r0 = " << r0 <<
'\n'
1467 <<
" theNNDistance = " << theNNDistance <<
'\n'
1468 <<
" maxInteractionDistance = " << maxInteractionDistance <<
'\n');
1472 maxInteractionDistance = r0 + theNbarNDistance;
1473 INCL_DEBUG(
"Initialised interaction distance: r0 = " << r0 <<
'\n'
1474 <<
" theNbarNDistance = " << theNbarNDistance <<
'\n'
1475 <<
" maxInteractionDistance = " << maxInteractionDistance <<
'\n');
1483 IsotopicDistribution
const &anIsotopicDistribution =
1485 IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
1486 for(
IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
1489 const G4double maximumRadius = std::max(pMaximumRadius, nMaximumRadius);
1490 rMax = std::max(maximumRadius, rMax);
1495 const G4double maximumRadius = std::max(pMaximumRadius, nMaximumRadius);
1496 rMax = std::max(maximumRadius, rMax);
1501 }
else if(p.theType==
PiPlus
1506 }
else if(p.theType==
KPlus
1507 || p.theType==
KZero) {
1514 }
else if(p.theType==
Lambda
1522 maxUniverseRadius = rMax;
1530 INCL_DEBUG(
"Initialised universe radius: " << maxUniverseRadius <<
'\n');
1540 for(
IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
1543 const G4double maximumRadius = std::max(pMaximumRadius, nMaximumRadius);
1544 rMax = std::max(maximumRadius, rMax);
1549 const G4double maximumRadius = std::max(pMaximumRadius, nMaximumRadius);
1550 rMax = std::max(maximumRadius, rMax);
1556 void INCL::updateGlobalInfo() {
1564 if(forceTransparent)
1584 G4double INCL::read_file(std::string filename, std::vector<G4double>& probabilities,
1585 std::vector<std::vector<G4String>>& particle_types) {
1586 std::ifstream file(filename);
1588 if (file.is_open()) {
1590 while (getline(file, line)) {
1591 std::istringstream iss(line);
1595 probabilities.push_back(prob);
1596 std::vector<G4String> types;
1598 while (iss >> type) {
1599 types.push_back(type);
1601 particle_types.push_back(std::move(types));
1604#ifdef INCLXX_IN_GEANT4_MODE
1605 G4cout <<
"ERROR no fread_file " << filename <<
G4endl;
1607 std::cout <<
"ERROR no fread_file " << filename << std::endl;
1614 G4int INCL::findStringNumber(
G4double rdm, std::vector<G4double> yields) {
1615 G4int stringNumber = -1;
1619 for (
G4int i = 0; i < static_cast<G4int>(yields.size()-1); i++) {
1620 if (rdm >= smallestsum && rdm <= biggestsum) {
1624 smallestsum += yields[i];
1625 biggestsum += yields[i+1];
1627 if(stringNumber==-1) stringNumber =
static_cast<G4int>(yields.size());
1628 if(stringNumber==-1){
1629 INCL_ERROR(
"ERROR in findStringNumber (stringNumber=-1)");
1630#ifdef INCLXX_IN_GEANT4_MODE
1633 std::cout <<
"ERROR in findStringNumber" << std::endl;
1636 return stringNumber;
1642 theEventInfo.reset();
1647 theEventInfo.projectileType = projectileSpecies.theType;
1648 theEventInfo.Ap = -1;
1649 theEventInfo.Zp = -1;
1650 theEventInfo.Sp = 0;
1651 theEventInfo.Ep = kineticEnergy;
1652 theEventInfo.St = 0;
1653 theEventInfo.At = 1;
1654 theEventInfo.Zt = 1;
1659 theEventInfo.reset();
1664 theEventInfo.projectileType = projectileSpecies.theType;
1665 theEventInfo.Ap = -1;
1666 theEventInfo.Zp = 0;
1667 theEventInfo.Sp = 0;
1668 theEventInfo.Ep = kineticEnergy;
1669 theEventInfo.St = 0;
1670 theEventInfo.At = 1;
1671 theEventInfo.Zt = 1;
1674 void INCL::postCascade_pbarH1(
ParticleList const &outgoingParticles) {
1675 theEventInfo.nParticles = 0;
1678 theEventInfo.nRemnants = 0;
1679 theEventInfo.history.clear();
1682 for(
ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
1683 if( (*i)->isEta() || (*i)->isOmega() ) {
1684 INCL_DEBUG(
"Decay outgoing eta/omega particle:" <<
'\n'
1685 << (*i)->print() <<
'\n');
1686 const ThreeVector beta = -(*i)->boostVector();
1687 const G4double pionResonanceMass = (*i)->getMass();
1691 (*i)->setMomentum(ThreeVector());
1692 (*i)->setEnergy((*i)->getMass());
1695 IAvatar *
decay =
new DecayAvatar((*i), 0.0, NULL);
1696 FinalState *fs =
decay->getFinalState();
1698 Particle *
const theModifiedParticle = fs->getModifiedParticles().front();
1699 ParticleList const &created = fs->getCreatedParticles();
1700 Particle *
const theCreatedParticle1 = created.front();
1702 if (created.size() == 1) {
1706 ThreeVector newMomentum = theCreatedParticle1->getMomentum();
1707 newMomentum *= decayMomentum / newMomentum.mag();
1709 theCreatedParticle1->setTableMass();
1710 theCreatedParticle1->setMomentum(newMomentum);
1711 theCreatedParticle1->adjustEnergyFromMomentum();
1712 theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
1713 theCreatedParticle1->boost(beta);
1714 theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1716 theModifiedParticle->setTableMass();
1717 theModifiedParticle->setMomentum(-newMomentum);
1718 theModifiedParticle->adjustEnergyFromMomentum();
1719 theModifiedParticle->boost(beta);
1721 outgoingParticles2.push_back(theCreatedParticle1);
1722 outgoingParticles2.push_back(theModifiedParticle);
1724 else if (created.size() == 2) {
1725 Particle *
const theCreatedParticle2 = created.back();
1727 theCreatedParticle1->boost(beta);
1728 theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1729 theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
1730 theCreatedParticle2->boost(beta);
1731 theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1732 theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
1733 theModifiedParticle->boost(beta);
1735 outgoingParticles2.push_back(theCreatedParticle1);
1736 outgoingParticles2.push_back(theCreatedParticle2);
1737 outgoingParticles2.push_back(theModifiedParticle);
1740 INCL_ERROR(
"Wrong number (< 2) of created particles during the decay of a pion resonance");
1746 outgoingParticles2.push_back(*i);
1750 for(
ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
1751 theEventInfo.A[theEventInfo.nParticles] = (
Short_t)(*i)->getA();
1752 theEventInfo.Z[theEventInfo.nParticles] = (
Short_t)(*i)->getZ();
1753 theEventInfo.S[theEventInfo.nParticles] = (
Short_t)(*i)->getS();
1754 theEventInfo.EKin[theEventInfo.nParticles] = (*i)->getKineticEnergy();
1755 ThreeVector mom = (*i)->getMomentum();
1756 theEventInfo.px[theEventInfo.nParticles] = mom.getX();
1757 theEventInfo.py[theEventInfo.nParticles] = mom.getY();
1758 theEventInfo.pz[theEventInfo.nParticles] = mom.getZ();
1759 theEventInfo.theta[theEventInfo.nParticles] =
Math::toDegrees(mom.theta());
1760 theEventInfo.phi[theEventInfo.nParticles] =
Math::toDegrees(mom.phi());
1761 theEventInfo.origin[theEventInfo.nParticles] = -1;
1762#ifdef INCLXX_IN_GEANT4_MODE
1763 theEventInfo.parentResonancePDGCode[theEventInfo.nParticles] = (*i)->getParentResonancePDGCode();
1764 theEventInfo.parentResonanceID[theEventInfo.nParticles] = (*i)->getParentResonanceID();
1766 theEventInfo.history.push_back(
"");
1767 ParticleSpecies pt((*i)->getType());
1768 theEventInfo.PDGCode[theEventInfo.nParticles] = pt.getPDGCode();
1769 theEventInfo.nParticles++;
1771 theEventInfo.nCascadeParticles = theEventInfo.nParticles;
1777 theEventInfo.reset();
1782 theEventInfo.projectileType = projectileSpecies.theType;
1783 theEventInfo.Ap = -1;
1784 theEventInfo.Zp = -1;
1785 theEventInfo.Sp = 0;
1786 theEventInfo.Ep = kineticEnergy;
1787 theEventInfo.St = 0;
1788 theEventInfo.At = 2;
1789 theEventInfo.Zt = 1;
1794 theEventInfo.reset();
1799 theEventInfo.projectileType = projectileSpecies.theType;
1800 theEventInfo.Ap = -1;
1801 theEventInfo.Zp = 0;
1802 theEventInfo.Sp = 0;
1803 theEventInfo.Ep = kineticEnergy;
1804 theEventInfo.St = 0;
1805 theEventInfo.At = 2;
1806 theEventInfo.Zt = 1;
1810 theEventInfo.nParticles = 0;
1814 theEventInfo.nRemnants = 0;
1815 theEventInfo.history.clear();
1818 for(
ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
1819 if( (*i)->isEta() || (*i)->isOmega() ) {
1820 INCL_DEBUG(
"Decay outgoing eta/omega particle:" <<
'\n'
1821 << (*i)->print() <<
'\n');
1822 const ThreeVector beta = -(*i)->boostVector();
1823 const G4double pionResonanceMass = (*i)->getMass();
1827 (*i)->setMomentum(ThreeVector());
1828 (*i)->setEnergy((*i)->getMass());
1831 IAvatar *
decay =
new DecayAvatar((*i), 0.0, NULL);
1832 FinalState *fs =
decay->getFinalState();
1834 Particle *
const theModifiedParticle = fs->getModifiedParticles().front();
1835 ParticleList const &created = fs->getCreatedParticles();
1836 Particle *
const theCreatedParticle1 = created.front();
1838 if (created.size() == 1) {
1842 ThreeVector newMomentum = theCreatedParticle1->getMomentum();
1843 newMomentum *= decayMomentum / newMomentum.mag();
1845 theCreatedParticle1->setTableMass();
1846 theCreatedParticle1->setMomentum(newMomentum);
1847 theCreatedParticle1->adjustEnergyFromMomentum();
1848 theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
1849 theCreatedParticle1->boost(beta);
1850 theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1852 theModifiedParticle->setTableMass();
1853 theModifiedParticle->setMomentum(-newMomentum);
1854 theModifiedParticle->adjustEnergyFromMomentum();
1855 theModifiedParticle->boost(beta);
1857 outgoingParticles2.push_back(theCreatedParticle1);
1858 outgoingParticles2.push_back(theModifiedParticle);
1860 else if (created.size() == 2) {
1861 Particle *
const theCreatedParticle2 = created.back();
1863 theCreatedParticle1->boost(beta);
1864 theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1865 theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
1866 theCreatedParticle2->boost(beta);
1867 theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
1868 theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
1869 theModifiedParticle->boost(beta);
1871 outgoingParticles2.push_back(theCreatedParticle1);
1872 outgoingParticles2.push_back(theCreatedParticle2);
1873 outgoingParticles2.push_back(theModifiedParticle);
1876 INCL_ERROR(
"Wrong number (< 2) of created particles during the decay of a pion resonance");
1882 outgoingParticles2.push_back(*i);
1886 for(
ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
1887 theEventInfo.A[theEventInfo.nParticles] = (
Short_t)(*i)->getA();
1888 theEventInfo.Z[theEventInfo.nParticles] = (
Short_t)(*i)->getZ();
1889 theEventInfo.S[theEventInfo.nParticles] = (
Short_t)(*i)->getS();
1890 theEventInfo.EKin[theEventInfo.nParticles] = (*i)->getKineticEnergy();
1891 ThreeVector mom = (*i)->getMomentum();
1892 theEventInfo.px[theEventInfo.nParticles] = mom.getX();
1893 theEventInfo.py[theEventInfo.nParticles] = mom.getY();
1894 theEventInfo.pz[theEventInfo.nParticles] = mom.getZ();
1895 theEventInfo.theta[theEventInfo.nParticles] =
Math::toDegrees(mom.theta());
1896 theEventInfo.phi[theEventInfo.nParticles] =
Math::toDegrees(mom.phi());
1897 theEventInfo.origin[theEventInfo.nParticles] = -1;
1898#ifdef INCLXX_IN_GEANT4_MODE
1899 theEventInfo.parentResonancePDGCode[theEventInfo.nParticles] = (*i)->getParentResonancePDGCode();
1900 theEventInfo.parentResonanceID[theEventInfo.nParticles] = (*i)->getParentResonanceID();
1902 theEventInfo.history.push_back(
"");
1903 ParticleSpecies pt((*i)->getType());
1904 theEventInfo.PDGCode[theEventInfo.nParticles] = pt.getPDGCode();
1905 theEventInfo.nParticles++;
1908 for(
ParticleIter i=H2Particles.begin(), e=H2Particles.end(); i!=e; ++i ) {
1909 theEventInfo.A[theEventInfo.nParticles] = (
Short_t)(*i)->getA();
1910 theEventInfo.Z[theEventInfo.nParticles] = (
Short_t)(*i)->getZ();
1911 theEventInfo.S[theEventInfo.nParticles] = (
Short_t)(*i)->getS();
1912 theEventInfo.EKin[theEventInfo.nParticles] = (*i)->getKineticEnergy();
1913 ThreeVector mom = (*i)->getMomentum();
1914 theEventInfo.px[theEventInfo.nParticles] = mom.getX();
1915 theEventInfo.py[theEventInfo.nParticles] = mom.getY();
1916 theEventInfo.pz[theEventInfo.nParticles] = mom.getZ();
1917 theEventInfo.theta[theEventInfo.nParticles] =
Math::toDegrees(mom.theta());
1918 theEventInfo.phi[theEventInfo.nParticles] =
Math::toDegrees(mom.phi());
1919 theEventInfo.origin[theEventInfo.nParticles] = -1;
1920#ifdef INCLXX_IN_GEANT4_MODE
1921 theEventInfo.parentResonancePDGCode[theEventInfo.nParticles] = (*i)->getParentResonancePDGCode();
1922 theEventInfo.parentResonanceID[theEventInfo.nParticles] = (*i)->getParentResonanceID();
1924 theEventInfo.history.push_back(
"");
1925 ParticleSpecies pt((*i)->getType());
1926 theEventInfo.PDGCode[theEventInfo.nParticles] = pt.getPDGCode();
1927 theEventInfo.nParticles++;
1929 theEventInfo.nCascadeParticles = theEventInfo.nParticles;
G4double S(G4double temp)
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
Alternative CascadeAction for dumping avatars.
Class containing default actions to be performed at intermediate cascade steps.
Static class for cluster formation.
Static class for selecting Coulomb distortion.
Simple container for output of calculation-wide results.
Abstract interface to the nuclear potential.
Simple class for computing intersections between a straight line and a sphere.
Functions that encapsulate a mass table.
G4GLOB_DLL std::ostream G4cout
static void setBias(const G4double b)
Set the global bias factor.
static void setCutNN(const G4double c)
ParticleList const & getParticles() const
void finalizeGlobalInfo(Random::SeedVector const &initialSeeds)
G4bool prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z, const G4int S)
INCL(Config const *const config)
const EventInfo & processEvent()
G4double initUniverseRadiusForAntiprotonAtRest(const G4int A, const G4int Z)
G4bool initializeTarget(const G4int A, const G4int Z, const G4int S, AnnihilationType theAType)
static void deleteBackupParticles()
Release the memory allocated for the backup particles.
Class that stores isotopic abundances for a given element.
IsotopeVector const & getIsotopes() const
Get the isotope vector.
ProjectileRemnant * getProjectileRemnant() const
Get the projectile remnant.
AnnihilationType getAnnihilationType() const
Getter for theAnnihilationType.
G4bool getTryCompoundNucleus()
G4int getS() const
Returns the strangeness number.
static std::vector< G4double > INCLBiasVector
Time ordered vector of all bias applied.
G4int getZ() const
Returns the charge number.
static G4double getTotalBias()
General bias vector function.
static G4ThreadLocal G4int nextBiasedCollisionID
G4int getA() const
Returns the baryon number.
void addToOutgoing(Particle *p)
add the particle to the outgoing particle list.
ParticleList extractDynamicalSpectators()
Returns a list of dynamical spectators.
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
void initialize(Config const *const theConfig)
Initialize the clustering model based on the Config object.
void deleteClusteringModel()
Delete the clustering model.
void initialize(Config const *const theConfig)
Initialize the Coulomb-distortion algorithm.
void deleteCoulomb()
Delete the Coulomb-distortion object.
void distortOut(ParticleList const &pL, Nucleus const *const n)
Modify the momentum of an outgoing particle.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4double interactionDistanceNbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy)
G4double interactionDistanceKbarN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
G4double interactionDistancePiN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
G4double interactionDistancenbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy)
G4double interactionDistanceKN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
G4double interactionDistanceYN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
void deleteCrossSections()
void initialize(Config const *const theConfig)
G4double interactionDistanceNN(const ParticleSpecies &aSpecies, const G4double kineticEnergy)
Compute the "interaction distance".
Intersection getEarlierTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the first intersection of a straight particle trajectory with a sphere.
G4double momentumInCM(Particle const *const p1, Particle const *const p2)
gives the momentum in the CM frame of two particles.
void initVerbosityLevelFromEnvvar()
G4double toDegrees(G4double radians)
void clearCache()
Clear the INuclearPotential cache.
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
void initialize(Config const *const theConfig=0)
Initialize the particle table.
G4int drawRandomNaturalIsotope(const G4int Z)
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2).
G4double getMaximumNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
void initialize(Config const *const aConfig)
Initialise blockers according to a Config object.
void deleteBlockers()
Delete blockers.
void initialize(Config const *const theConfig)
void deletePhaseSpaceGenerator()
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.
const G4double eSquared
Coulomb conversion factor [MeV*fm].
ThreeVector normVector(G4double norm=1.)
Adapter const & getAdapter()
void initialize(Config const *const)
Initialize generator according to a Config object.
Solution solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
ParticleList::const_iterator ParticleIter
IsotopeVector::iterator IsotopeIter
std::vector< Isotope > IsotopeVector
std::vector< Base * > ParticleList
Bool_t pionAbsorption
True if the event is a pion absorption.
void reset()
Reset the EventInfo members.
Short_t At
Mass number of the target nucleus.
Short_t Zp
Charge number of the projectile nucleus.
Bool_t annihilationP
True if annihilation at rest on a proton.
Int_t projectileType
Projectile particle type.
Float_t Ep
Projectile kinetic energy given as input.
Short_t nCascadeParticles
Number of cascade particles.
Bool_t transparent
True if the event is transparent.
Bool_t nucleonAbsorption
True if the event is a nucleon absorption.
Short_t St
Strangeness number of the target nucleus.
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
Short_t Ap
Mass number of the projectile nucleus.
Short_t Sp
Strangeness number of the projectile nucleus.
Bool_t annihilationN
True if annihilation at rest on a neutron.
Short_t Zt
Charge number of the target nucleus.
static G4ThreadLocal Int_t eventNumber
Number of the event.
Int_t nNucleonAbsorptions
Number of nucleon absorptions (no outcoming particles).
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
Int_t nShots
Number of shots.
Int_t nPionAbsorptions
Number of nucleon absorptions (no outcoming pions).
Int_t nCompleteFusion
Number of complete-fusion events (nParticles==0).
Int_t nTransparents
Number of transparent shots.
Int_t nForcedCompoundNucleus
Number of forced compound-nucleus events.
Int_t nForcedTransparents
Number of forced transparents.