Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/incl_physics/src/G4INCLCascade.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/hadronic/models/inclxx/incl_physics/src/G4INCLCascade.cc (Version 11.3.0) and /processes/hadronic/models/inclxx/incl_physics/src/G4INCLCascade.cc (Version 10.3.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // INCL++ intra-nuclear cascade model              26 // INCL++ intra-nuclear cascade model
 27 // Alain Boudard, CEA-Saclay, France               27 // Alain Boudard, CEA-Saclay, France
 28 // Joseph Cugnon, University of Liege, Belgium     28 // Joseph Cugnon, University of Liege, Belgium
 29 // Jean-Christophe David, CEA-Saclay, France       29 // Jean-Christophe David, CEA-Saclay, France
 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H     30 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
 31 // Sylvie Leray, CEA-Saclay, France                31 // Sylvie Leray, CEA-Saclay, France
 32 // Davide Mancusi, CEA-Saclay, France              32 // Davide Mancusi, CEA-Saclay, France
 33 //                                                 33 //
 34 #define INCLXX_IN_GEANT4_MODE 1                    34 #define INCLXX_IN_GEANT4_MODE 1
 35                                                    35 
 36 #include "globals.hh"                              36 #include "globals.hh"
 37                                                    37 
 38 /** \file G4INCLCascade.cc                         38 /** \file G4INCLCascade.cc
 39  *                                                 39  *
 40  * INCL Cascade                                    40  * INCL Cascade
 41  */                                                41  */
 42 #include "G4INCLCascade.hh"                        42 #include "G4INCLCascade.hh"
 43 #include "G4INCLRandom.hh"                         43 #include "G4INCLRandom.hh"
 44 #include "G4INCLStandardPropagationModel.hh"       44 #include "G4INCLStandardPropagationModel.hh"
 45 #include "G4INCLParticleTable.hh"                  45 #include "G4INCLParticleTable.hh"
 46 #include "G4INCLParticle.hh"                   << 
 47 #include "G4INCLNuclearMassTable.hh"               46 #include "G4INCLNuclearMassTable.hh"
 48 #include "G4INCLGlobalInfo.hh"                     47 #include "G4INCLGlobalInfo.hh"
 49 #include "G4INCLNucleus.hh"                    << 
 50                                                    48 
 51 #include "G4INCLPauliBlocking.hh"                  49 #include "G4INCLPauliBlocking.hh"
 52                                                    50 
 53 #include "G4INCLCrossSections.hh"                  51 #include "G4INCLCrossSections.hh"
 54                                                    52 
 55 #include "G4INCLPhaseSpaceGenerator.hh"            53 #include "G4INCLPhaseSpaceGenerator.hh"
 56                                                    54 
 57 #include "G4INCLLogger.hh"                         55 #include "G4INCLLogger.hh"
 58 #include "G4INCLGlobals.hh"                        56 #include "G4INCLGlobals.hh"
 59 #include "G4INCLNuclearDensityFactory.hh"          57 #include "G4INCLNuclearDensityFactory.hh"
 60                                                    58 
 61 #include "G4INCLINuclearPotential.hh"              59 #include "G4INCLINuclearPotential.hh"
 62                                                    60 
 63 #include "G4INCLCoulombDistortion.hh"              61 #include "G4INCLCoulombDistortion.hh"
 64                                                    62 
 65 #include "G4INCLClustering.hh"                     63 #include "G4INCLClustering.hh"
 66                                                    64 
 67 #include "G4INCLIntersection.hh"                   65 #include "G4INCLIntersection.hh"
 68                                                    66 
 69 #include "G4INCLBinaryCollisionAvatar.hh"          67 #include "G4INCLBinaryCollisionAvatar.hh"
 70                                                    68 
 71 #include "G4INCLCascadeAction.hh"                  69 #include "G4INCLCascadeAction.hh"
 72 #include "G4INCLAvatarDumpAction.hh"               70 #include "G4INCLAvatarDumpAction.hh"
 73                                                    71 
 74 #include <cstring>                             <<  72 #include <cstring>
 75 #include <cstdlib>                                 73 #include <cstdlib>
 76 #include <numeric>                                 74 #include <numeric>
 77                                                    75 
 78 #include "G4INCLPbarAtrestEntryChannel.hh"     << 
 79                                                << 
 80 namespace G4INCL {                                 76 namespace G4INCL {
 81                                                <<  77 
 82   INCL::INCL(Config const * const config)          78   INCL::INCL(Config const * const config)
 83     :propagationModel(0), theA(208), theZ(82), <<  79     :propagationModel(0), theA(208), theZ(82),
 84     targetInitSuccess(false),                      80     targetInitSuccess(false),
 85     maxImpactParameter(0.),                        81     maxImpactParameter(0.),
 86     maxUniverseRadius(0.),                         82     maxUniverseRadius(0.),
 87     maxInteractionDistance(0.),                    83     maxInteractionDistance(0.),
 88     fixedImpactParameter(0.),                      84     fixedImpactParameter(0.),
 89     theConfig(config),                             85     theConfig(config),
 90     nucleus(NULL),                                 86     nucleus(NULL),
 91     forceTransparent(false),                       87     forceTransparent(false),
 92     minRemnantSize(4)                              88     minRemnantSize(4)
 93   {                                                89   {
 94     // Set the logger object.                      90     // Set the logger object.
 95 #ifdef INCLXX_IN_GEANT4_MODE                       91 #ifdef INCLXX_IN_GEANT4_MODE
 96     Logger::initVerbosityLevelFromEnvvar();        92     Logger::initVerbosityLevelFromEnvvar();
 97 #else // INCLXX_IN_GEANT4_MODE                     93 #else // INCLXX_IN_GEANT4_MODE
 98     Logger::initialize(theConfig);                 94     Logger::initialize(theConfig);
 99 #endif // INCLXX_IN_GEANT4_MODE                    95 #endif // INCLXX_IN_GEANT4_MODE
100                                                    96 
101     // Set the random number generator algorit     97     // Set the random number generator algorithm. The system can support
102     // multiple different generator algorithms     98     // multiple different generator algorithms in a completely
103     // transparent way.                            99     // transparent way.
104     Random::initialize(theConfig);                100     Random::initialize(theConfig);
105                                                   101 
106     // Select the Pauli and CDPP blocking algo    102     // Select the Pauli and CDPP blocking algorithms
107     Pauli::initialize(theConfig);                 103     Pauli::initialize(theConfig);
108                                                   104 
109     // Set the cross-section set                  105     // Set the cross-section set
110     CrossSections::initialize(theConfig);         106     CrossSections::initialize(theConfig);
111                                                   107 
112     // Set the phase-space generator              108     // Set the phase-space generator
113     PhaseSpaceGenerator::initialize(theConfig)    109     PhaseSpaceGenerator::initialize(theConfig);
114                                                   110 
115     // Select the Coulomb-distortion algorithm    111     // Select the Coulomb-distortion algorithm:
116     CoulombDistortion::initialize(theConfig);     112     CoulombDistortion::initialize(theConfig);
117                                                   113 
118     // Select the clustering algorithm:           114     // Select the clustering algorithm:
119     Clustering::initialize(theConfig);            115     Clustering::initialize(theConfig);
120                                                   116 
121     // Initialize the INCL particle table:        117     // Initialize the INCL particle table:
122     ParticleTable::initialize(theConfig);         118     ParticleTable::initialize(theConfig);
123                                                   119 
124     // Initialize the value of cutNN in Binary    120     // Initialize the value of cutNN in BinaryCollisionAvatar
125     BinaryCollisionAvatar::setCutNN(theConfig-    121     BinaryCollisionAvatar::setCutNN(theConfig->getCutNN());
126                                                   122 
127     // Initialize the value of strange cross s << 
128     BinaryCollisionAvatar::setBias(theConfig-> << 
129                                                << 
130     // Propagation model is responsible for fi    123     // Propagation model is responsible for finding avatars and
131     // transporting the particles. In principl    124     // transporting the particles. In principle this step is "hidden"
132     // behind an abstract interface and the re    125     // behind an abstract interface and the rest of the system does not
133     // care how the transportation and avatar     126     // care how the transportation and avatar finding is done. This
134     // should allow us to "easily" experiment     127     // should allow us to "easily" experiment with different avatar
135     // finding schemes and even to support thi    128     // finding schemes and even to support things like curved
136     // trajectories in the future.                129     // trajectories in the future.
137     propagationModel = new StandardPropagation    130     propagationModel = new StandardPropagationModel(theConfig->getLocalEnergyBBType(),theConfig->getLocalEnergyPiType(),theConfig->getHadronizationTime());
138     if(theConfig->getCascadeActionType() == Av    131     if(theConfig->getCascadeActionType() == AvatarDumpActionType)
139       cascadeAction = new AvatarDumpAction();     132       cascadeAction = new AvatarDumpAction();
140     else                                          133     else
141       cascadeAction = new CascadeAction();        134       cascadeAction = new CascadeAction();
142     cascadeAction->beforeRunAction(theConfig);    135     cascadeAction->beforeRunAction(theConfig);
143                                                   136 
144     theGlobalInfo.cascadeModel = theConfig->ge    137     theGlobalInfo.cascadeModel = theConfig->getVersionString();
145     theGlobalInfo.deexcitationModel = theConfi    138     theGlobalInfo.deexcitationModel = theConfig->getDeExcitationString();
146 #ifdef INCL_ROOT_USE                              139 #ifdef INCL_ROOT_USE
147     theGlobalInfo.rootSelection = theConfig->g    140     theGlobalInfo.rootSelection = theConfig->getROOTSelectionString();
148 #endif                                            141 #endif
149                                                   142 
150 #ifndef INCLXX_IN_GEANT4_MODE                     143 #ifndef INCLXX_IN_GEANT4_MODE
151     // Fill in the global information             144     // Fill in the global information
152     theGlobalInfo.At = theConfig->getTargetA()    145     theGlobalInfo.At = theConfig->getTargetA();
153     theGlobalInfo.Zt = theConfig->getTargetZ()    146     theGlobalInfo.Zt = theConfig->getTargetZ();
154     theGlobalInfo.St = theConfig->getTargetS() << 
155     const ParticleSpecies theSpecies = theConf    147     const ParticleSpecies theSpecies = theConfig->getProjectileSpecies();
156     theGlobalInfo.Ap = theSpecies.theA;           148     theGlobalInfo.Ap = theSpecies.theA;
157     theGlobalInfo.Zp = theSpecies.theZ;           149     theGlobalInfo.Zp = theSpecies.theZ;
158     theGlobalInfo.Sp = theSpecies.theS;        << 
159     theGlobalInfo.Ep = theConfig->getProjectil    150     theGlobalInfo.Ep = theConfig->getProjectileKineticEnergy();
160     theGlobalInfo.biasFactor = theConfig->getB << 
161 #endif                                            151 #endif
162                                                   152 
163     fixedImpactParameter = theConfig->getImpac    153     fixedImpactParameter = theConfig->getImpactParameter();
164   }                                               154   }
165                                                   155 
166   INCL::~INCL() {                                 156   INCL::~INCL() {
167     InteractionAvatar::deleteBackupParticles()    157     InteractionAvatar::deleteBackupParticles();
168 #ifndef INCLXX_IN_GEANT4_MODE                     158 #ifndef INCLXX_IN_GEANT4_MODE
169     NuclearMassTable::deleteTable();              159     NuclearMassTable::deleteTable();
170 #endif                                            160 #endif
171     PhaseSpaceGenerator::deletePhaseSpaceGener    161     PhaseSpaceGenerator::deletePhaseSpaceGenerator();
172     CrossSections::deleteCrossSections();         162     CrossSections::deleteCrossSections();
173     Pauli::deleteBlockers();                      163     Pauli::deleteBlockers();
174     CoulombDistortion::deleteCoulomb();           164     CoulombDistortion::deleteCoulomb();
175     Random::deleteGenerator();                    165     Random::deleteGenerator();
176     Clustering::deleteClusteringModel();          166     Clustering::deleteClusteringModel();
177 #ifndef INCLXX_IN_GEANT4_MODE                     167 #ifndef INCLXX_IN_GEANT4_MODE
178     Logger::deleteLoggerSlave();                  168     Logger::deleteLoggerSlave();
179 #endif                                            169 #endif
180     NuclearDensityFactory::clearCache();          170     NuclearDensityFactory::clearCache();
181     NuclearPotential::clearCache();               171     NuclearPotential::clearCache();
182     cascadeAction->afterRunAction();              172     cascadeAction->afterRunAction();
183     delete cascadeAction;                         173     delete cascadeAction;
184     delete propagationModel;                      174     delete propagationModel;
185     delete theConfig;                             175     delete theConfig;
186   }                                               176   }
187                                                   177 
188   G4bool INCL::prepareReaction(const ParticleS << 178   G4bool INCL::prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z) {
189     if(A < 0 || A > 300 || Z < 1 || Z > 200) {    179     if(A < 0 || A > 300 || Z < 1 || Z > 200) {
190       INCL_ERROR("Unsupported target: A = " << << 180       INCL_ERROR("Unsupported target: A = " << A << " Z = " << Z << '\n'
191                  << "Target configuration reje    181                  << "Target configuration rejected." << '\n');
192       return false;                               182       return false;
193     }                                             183     }
194     if(projectileSpecies.theType==Composite &&    184     if(projectileSpecies.theType==Composite &&
195        (projectileSpecies.theZ==projectileSpec    185        (projectileSpecies.theZ==projectileSpecies.theA || projectileSpecies.theZ==0)) {
196       INCL_ERROR("Unsupported projectile: A =  << 186       INCL_ERROR("Unsupported projectile: A = " << projectileSpecies.theA << " Z = " << projectileSpecies.theZ << '\n'
197                  << "Projectile configuration     187                  << "Projectile configuration rejected." << '\n');
198       return false;                               188       return false;
199     }                                             189     }
200                                                   190 
201     // Reset the forced-transparent flag          191     // Reset the forced-transparent flag
202     forceTransparent = false;                     192     forceTransparent = false;
203                                                   193 
204     // Initialise the maximum universe radius     194     // Initialise the maximum universe radius
205     initUniverseRadius(projectileSpecies, kine    195     initUniverseRadius(projectileSpecies, kineticEnergy, A, Z);
206     // Initialise the nucleus                  << 
207                                                   196 
208 //D                                            << 197     // Initialise the nucleus
209     //reset                                    << 198     theZ = Z;
210     G4bool ProtonIsTheVictim = false;          << 199     if(theConfig->isNaturalTarget())
211     G4bool NeutronIsTheVictim = false;         << 200       theA = ParticleTable::drawRandomNaturalIsotope(Z);
212     theEventInfo.annihilationP = false;        << 201     else
213     theEventInfo.annihilationN = false;        << 202       theA = A;
214                                                << 203     initializeTarget(theA, theZ);
215     //G4double AnnihilationBarrier = kineticEn << 
216     if(projectileSpecies.theType == antiProton << 
217       G4double SpOverSn = 1.331;//from experim << 
218       //INCL_WARN("theA number set to A-1 from << 
219                                                << 
220       G4double neutronprob;                    << 
221       if(theConfig->isNaturalTarget()){ // A = << 
222         theA = ParticleTable::drawRandomNatura << 
223         neutronprob = (theA + 1 - Z)/(theA + 1 << 
224       }                                        << 
225       else{                                    << 
226         theA = A - 1;                          << 
227         neutronprob = (A - Z)/(A - Z + SpOverS << 
228       }                                        << 
229                                                << 
230       theS = S;                                << 
231                                                << 
232       G4double rndm = Random::shoot();         << 
233       if(rndm >= neutronprob){     //proton is << 
234         theEventInfo.annihilationP = true;     << 
235         theZ = Z - 1;                          << 
236         ProtonIsTheVictim = true;              << 
237         //INCL_WARN("theZ number set to Z-1 fr << 
238       }                                        << 
239       else{        //neutron is annihilated    << 
240         theEventInfo.annihilationN = true;     << 
241         theZ = Z;                              << 
242         NeutronIsTheVictim = true;             << 
243       }                                        << 
244     }                                          << 
245     else{ // not annihilation of pbar          << 
246       theZ = Z;                                << 
247       theS = S;                                << 
248       if(theConfig->isNaturalTarget())         << 
249         theA = ParticleTable::drawRandomNatura << 
250       else                                     << 
251         theA = A;                              << 
252     }                                          << 
253                                                << 
254     AnnihilationType theAType = Def;           << 
255     if(ProtonIsTheVictim == true && NeutronIsT << 
256     theAType = PType;                          << 
257     if(NeutronIsTheVictim == true && ProtonIsT << 
258     theAType = NType;                          << 
259                                                << 
260 //D                                            << 
261                                                   204 
262     initializeTarget(theA, theZ, theS, theATyp << 
263                                                << 
264     // Set the maximum impact parameter           205     // Set the maximum impact parameter
265     maxImpactParameter = CoulombDistortion::ma    206     maxImpactParameter = CoulombDistortion::maxImpactParameter(projectileSpecies, kineticEnergy, nucleus);
266     INCL_DEBUG("Maximum impact parameter initi    207     INCL_DEBUG("Maximum impact parameter initialised: " << maxImpactParameter << '\n');
267                                                   208 
268     // For forced CN events                       209     // For forced CN events
269     initMaxInteractionDistance(projectileSpeci    210     initMaxInteractionDistance(projectileSpecies, kineticEnergy);
270 // Set the geometric cross sectiony section    << 211 
271     if(projectileSpecies.theType == antiProton << 212     // Set the geometric cross section
272       G4int currentA = A;                      << 213     theGlobalInfo.geometricCrossSection =
273       if(theConfig->isNaturalTarget()){        << 214       Math::tenPi*std::pow(maxImpactParameter,2);
274         currentA = ParticleTable::drawRandomNa << 
275       }                                        << 
276       G4double kineticEnergy2=kineticEnergy;   << 
277       if (kineticEnergy2 <= 0.) kineticEnergy2 << 
278       theGlobalInfo.geometricCrossSection = 9. << 
279         Math::pi*std::pow((1.840 + 1.120*std:: << 
280         (1. + (Z*G4INCL::PhysicalConstants::eS << 
281          //xsection formula was borrowed from  << 
282     }                                          << 
283     else{                                      << 
284       theGlobalInfo.geometricCrossSection =    << 
285         Math::tenPi*std::pow(maxImpactParamete << 
286     }                                          << 
287                                                   215 
288     // Set the minimum remnant size               216     // Set the minimum remnant size
289     if(projectileSpecies.theA > 0)                217     if(projectileSpecies.theA > 0)
290       minRemnantSize = std::min(theA, 4);         218       minRemnantSize = std::min(theA, 4);
291     else                                          219     else
292       minRemnantSize = std::min(theA-1, 4);       220       minRemnantSize = std::min(theA-1, 4);
                                                   >> 221 
293     return true;                                  222     return true;
294   }                                               223   }
295                                                   224 
296   G4bool INCL::initializeTarget(const G4int A, << 225   G4bool INCL::initializeTarget(const G4int A, const G4int Z) {
297     delete nucleus;                               226     delete nucleus;
298                                                   227 
299     if (theAType==PType || theAType==NType) {  << 228     nucleus = new Nucleus(A, Z, theConfig, maxUniverseRadius);
300       G4double newmaxUniverseRadius=0.;        << 
301       if (theAType==PType) newmaxUniverseRadiu << 
302       else newmaxUniverseRadius=initUniverseRa << 
303       nucleus = new Nucleus(A, Z, S, theConfig << 
304     }                                          << 
305     else{                                      << 
306       nucleus = new Nucleus(A, Z, S, theConfig << 
307     }                                          << 
308     nucleus->getStore()->getBook().reset();       229     nucleus->getStore()->getBook().reset();
309     nucleus->initializeParticles();               230     nucleus->initializeParticles();
                                                   >> 231 
310     propagationModel->setNucleus(nucleus);        232     propagationModel->setNucleus(nucleus);
311     return true;                                  233     return true;
312   }                                               234   }
313                                                   235 
314   const EventInfo &INCL::processEvent(            236   const EventInfo &INCL::processEvent(
315       ParticleSpecies const &projectileSpecies    237       ParticleSpecies const &projectileSpecies,
316       const G4double kineticEnergy,               238       const G4double kineticEnergy,
317       const G4int targetA,                        239       const G4int targetA,
318       const G4int targetZ,                     << 240       const G4int targetZ
319       const G4int targetS                      << 
320       ) {                                         241       ) {
321                                                << 
322     ParticleList starlistH2;                   << 
323                                                << 
324     if (projectileSpecies.theType==antiProton  << 
325                                                << 
326       if (targetA==1) {                        << 
327         preCascade_pbarH1(projectileSpecies, k << 
328       } else {                                 << 
329         preCascade_pbarH2(projectileSpecies, k << 
330         theEventInfo.annihilationP = false;    << 
331         theEventInfo.annihilationN = false;    << 
332                                                << 
333         G4double SpOverSn = 1.331;  //from exp << 
334                                                << 
335         ThreeVector dummy(0.,0.,0.);           << 
336         G4double rndm = Random::shoot()*(SpOve << 
337         if (rndm <= SpOverSn) {  //proton is a << 
338           theEventInfo.annihilationP = true;   << 
339           Particle *p2 = new Particle(Neutron, << 
340           starlistH2.push_back(p2);            << 
341           //delete p2;                         << 
342         } else {                 //neutron is  << 
343           theEventInfo.annihilationN = true;   << 
344           Particle *p2 = new Particle(Proton,  << 
345           starlistH2.push_back(p2);            << 
346           //delete p2;                         << 
347         }                                      << 
348       }                                        << 
349                                                << 
350       // File names                            << 
351 #ifdef INCLXX_IN_GEANT4_MODE                   << 
352       if (!G4FindDataDir("G4INCLDATA") ) {     << 
353         G4ExceptionDescription ed;             << 
354         ed << " Data missing: set environment  << 
355            << " to point to the directory cont << 
356            << " by the INCL++ model" << G4endl << 
357         G4Exception("G4INCLDataFile::readData( << 
358       }                                        << 
359       const G4String& dataPath0(G4FindDataDir( << 
360       const G4String& dataPathppbar(dataPath0  << 
361 //      const G4String& dataPathnpbar(dataPath << 
362       const G4String& dataPathppbark(dataPath0 << 
363 //      const G4String& dataPathnpbark(dataPat << 
364 #else                                          << 
365       std::string path;                        << 
366       if (theConfig) path = theConfig->getINCL << 
367       const std::string& dataPathppbar(path +  << 
368       INCL_DEBUG("Reading https://doi.org/10.1 << 
369       const std::string& dataPathnpbar(path +  << 
370       INCL_DEBUG("Reading https://doi.org/10.1 << 
371       const std::string& dataPathppbark(path + << 
372       INCL_DEBUG("Reading https://doi.org/10.1 << 
373       const std::string& dataPathnpbark(path + << 
374       INCL_DEBUG("Reading https://doi.org/10.1 << 
375 #endif                                         << 
376                                                << 
377       //read probabilities and particle types  << 
378       std::vector<G4double> probabilities;  // << 
379       std::vector<std::vector<G4String>> parti << 
380       G4double sum = 0.0;  //will contain a su << 
381       G4double kaonicFSprob=0.05;  //probabili << 
382                                                << 
383       ParticleList starlist;                   << 
384       ThreeVector mommy;  //momentum to be ass << 
385                                                << 
386       G4double rdm = Random::shoot();          << 
387       ThreeVector annihilationPosition(0.,0.,0 << 
388       if (rdm < (1.-kaonicFSprob)) {  // pioni << 
389         INCL_DEBUG("pionic pp final state chos << 
390         sum = read_file(dataPathppbar, probabi << 
391         rdm = (rdm/(1.-kaonicFSprob))*sum;  // << 
392         //now get the line number in the file  << 
393         G4int n = findStringNumber(rdm, std::m << 
394         if ( n < 0 ) return theEventInfo;      << 
395         for (G4int j = 0; j < static_cast<G4in << 
396           if (particle_types[n][j] == "pi0") { << 
397             Particle *p = new Particle(PiZero, << 
398             starlist.push_back(p);             << 
399           } else if (particle_types[n][j] == " << 
400             Particle *p = new Particle(PiMinus << 
401             starlist.push_back(p);             << 
402           } else if (particle_types[n][j] == " << 
403             Particle *p = new Particle(PiPlus, << 
404             starlist.push_back(p);             << 
405           } else if (particle_types[n][j] == " << 
406             Particle *p = new Particle(Omega,  << 
407             starlist.push_back(p);             << 
408           } else if (particle_types[n][j] == " << 
409             Particle *p = new Particle(Eta, mo << 
410             starlist.push_back(p);             << 
411           } else if (particle_types[n][j] == " << 
412             Particle *p = new Particle(PiMinus << 
413             starlist.push_back(p);             << 
414             Particle *pp = new Particle(PiZero << 
415             starlist.push_back(pp);            << 
416           } else if (particle_types[n][j] == " << 
417             Particle *p = new Particle(PiPlus, << 
418             starlist.push_back(p);             << 
419             Particle *pp = new Particle(PiZero << 
420             starlist.push_back(pp);            << 
421           } else if (particle_types[n][j] == " << 
422             Particle *p = new Particle(PiMinus << 
423             starlist.push_back(p);             << 
424             Particle *pp = new Particle(PiPlus << 
425             starlist.push_back(pp);            << 
426           } else {                             << 
427             INCL_ERROR("Some non-existing FS p << 
428             for (G4int jj = 0; jj < static_cas << 
429 #ifdef INCLXX_IN_GEANT4_MODE                   << 
430               G4cout << "gotcha! " << particle << 
431 #else                                          << 
432               std::cout << "gotcha! " << parti << 
433 #endif                                         << 
434             }                                  << 
435 #ifdef INCLXX_IN_GEANT4_MODE                   << 
436             G4cout << "Some non-existing FS pa << 
437 #else                                          << 
438             std::cout << "Some non-existing FS << 
439 #endif                                         << 
440           }                                    << 
441         }                                      << 
442       } else {                                 << 
443         INCL_DEBUG("kaonic pp final state chos << 
444         sum = read_file(dataPathppbark, probab << 
445         rdm = ((1.-rdm)/kaonicFSprob)*sum;  // << 
446         //now get the line number in the file  << 
447         G4int n = findStringNumber(rdm, probab << 
448         if ( n < 0 ) return theEventInfo;      << 
449         for (G4int j = 0; j < static_cast<G4in << 
450           if (particle_types[n][j] == "pi0") { << 
451             Particle *p = new Particle(PiZero, << 
452             starlist.push_back(p);             << 
453           } else if (particle_types[n][j] == " << 
454             Particle *p = new Particle(PiMinus << 
455             starlist.push_back(p);             << 
456           } else if (particle_types[n][j] == " << 
457             Particle *p = new Particle(PiPlus, << 
458             starlist.push_back(p);             << 
459           } else if (particle_types[n][j] == " << 
460             Particle *p = new Particle(Omega,  << 
461             starlist.push_back(p);             << 
462           } else if (particle_types[n][j] == " << 
463             Particle *p = new Particle(Eta, mo << 
464             starlist.push_back(p);             << 
465           } else if (particle_types[n][j] == " << 
466             Particle *p = new Particle(KMinus, << 
467             starlist.push_back(p);             << 
468           } else if (particle_types[n][j] == " << 
469             Particle *p = new Particle(KPlus,  << 
470             starlist.push_back(p);             << 
471           } else if (particle_types[n][j] == " << 
472             Particle *p = new Particle(KZero,  << 
473             starlist.push_back(p);             << 
474           } else if (particle_types[n][j] == " << 
475             Particle *p = new Particle(KZeroBa << 
476             starlist.push_back(p);             << 
477           } else {                             << 
478             INCL_ERROR("Some non-existing FS p << 
479             for (G4int jj = 0; jj < static_cas << 
480 #ifdef INCLXX_IN_GEANT4_MODE                   << 
481               G4cout << "gotcha! " << particle << 
482 #else                                          << 
483               std::cout << "gotcha! " << parti << 
484 #endif                                         << 
485             }                                  << 
486 #ifdef INCLXX_IN_GEANT4_MODE                   << 
487             G4cout << "Some non-existing FS pa << 
488 #else                                          << 
489             std::cout << "Some non-existing FS << 
490 #endif                                         << 
491           }                                    << 
492         }                                      << 
493       }                                        << 
494                                                << 
495       //compute energies of mesons with a phas << 
496       G4double energyOfMesonStar=ParticleTable << 
497       if (starlist.size() < 2) {               << 
498         INCL_ERROR("should never happen, at le << 
499       } else if (starlist.size() == 2) {       << 
500         ParticleIter first = starlist.begin(); << 
501         ParticleIter last = std::next(first, 1 << 
502         G4double m1 = (*first)->getMass();     << 
503         G4double m2 = (*last)->getMass();      << 
504         G4double s = energyOfMesonStar*energyO << 
505         G4double mom1 = std::sqrt(s/4. - (std: << 
506         ThreeVector momentello = Random::normV << 
507         (*first)->setMomentum(momentello);     << 
508         (*first)->adjustEnergyFromMomentum();  << 
509         (*last)->setMomentum(-momentello);     << 
510         (*last)->adjustEnergyFromMomentum();   << 
511       } else {                                 << 
512         PhaseSpaceGenerator::generate(energyOf << 
513       }                                        << 
514                                                << 
515       if (targetA==1) postCascade_pbarH1(starl << 
516       else            postCascade_pbarH2(starl << 
517                                                << 
518       theGlobalInfo.nShots++;                  << 
519       return theEventInfo;                     << 
520     }  // pbar on H1                           << 
521                                                << 
522     // ReInitialize the bias vector            << 
523     Particle::INCLBiasVector.clear();          << 
524     //Particle::INCLBiasVector.Clear();        << 
525     Particle::nextBiasedCollisionID = 0;       << 
526                                                << 
527     // Set the target and the projectile          242     // Set the target and the projectile
528     targetInitSuccess = prepareReaction(projec << 243     targetInitSuccess = prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ);
529                                                   244 
530     if(!targetInitSuccess) {                      245     if(!targetInitSuccess) {
531       INCL_WARN("Target initialisation failed  << 246       INCL_WARN("Target initialisation failed for A=" << targetA << ", Z=" << targetZ << '\n');
532       theEventInfo.transparent=true;              247       theEventInfo.transparent=true;
533       return theEventInfo;                        248       return theEventInfo;
534     }                                             249     }
535                                                   250 
536     cascadeAction->beforeCascadeAction(propaga    251     cascadeAction->beforeCascadeAction(propagationModel);
537                                                   252 
538     const G4bool canRunCascade = preCascade(pr    253     const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
539     if(canRunCascade) {                           254     if(canRunCascade) {
540       cascade();                                  255       cascade();
541       postCascade(projectileSpecies, kineticEn << 256       postCascade();
542       cascadeAction->afterCascadeAction(nucleu    257       cascadeAction->afterCascadeAction(nucleus);
543     }                                             258     }
544     updateGlobalInfo();                           259     updateGlobalInfo();
545     return theEventInfo;                          260     return theEventInfo;
546   }                                               261   }
547                                                   262 
548   G4bool INCL::preCascade(ParticleSpecies cons    263   G4bool INCL::preCascade(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
549     // Reset theEventInfo                         264     // Reset theEventInfo
550     theEventInfo.reset();                         265     theEventInfo.reset();
551                                                << 266 
552     EventInfo::eventNumber++;                     267     EventInfo::eventNumber++;
553                                                   268 
554     // Fill in the event information              269     // Fill in the event information
555     theEventInfo.projectileType = projectileSp    270     theEventInfo.projectileType = projectileSpecies.theType;
556     theEventInfo.Ap = (Short_t)projectileSpeci << 271     theEventInfo.Ap = projectileSpecies.theA;
557     theEventInfo.Zp = (Short_t)projectileSpeci << 272     theEventInfo.Zp = projectileSpecies.theZ;
558     theEventInfo.Sp = (Short_t)projectileSpeci << 
559     theEventInfo.Ep = kineticEnergy;              273     theEventInfo.Ep = kineticEnergy;
560     theEventInfo.St = (Short_t)nucleus->getS() << 274     theEventInfo.At = nucleus->getA();
                                                   >> 275     theEventInfo.Zt = nucleus->getZ();
561                                                   276 
562     if(nucleus->getAnnihilationType()==PType){ << 
563       theEventInfo.annihilationP = true;       << 
564       theEventInfo.At = (Short_t)nucleus->getA << 
565       theEventInfo.Zt = (Short_t)nucleus->getZ << 
566     }                                          << 
567     else if(nucleus->getAnnihilationType()==NT << 
568       theEventInfo.annihilationN = true;       << 
569       theEventInfo.At = (Short_t)nucleus->getA << 
570       theEventInfo.Zt = (Short_t)nucleus->getZ << 
571     }                                          << 
572     else {                                     << 
573       theEventInfo.At = (Short_t)nucleus->getA << 
574       theEventInfo.Zt = (Short_t)nucleus->getZ << 
575     }                                          << 
576     // Do nothing below the Coulomb barrier       277     // Do nothing below the Coulomb barrier
577     if(maxImpactParameter<=0.) {                  278     if(maxImpactParameter<=0.) {
578       // Fill in the event information            279       // Fill in the event information
579     //Particle *pbar = new Particle;           << 280       theEventInfo.transparent = true;
580     //PbarAtrestEntryChannel *obj = new PbarAt << 281 
581       if(projectileSpecies.theType == antiProt << 282       return false;
582         INCL_DEBUG("at rest annihilation" << ' << 
583         //theEventInfo.transparent = false;    << 
584       } else {                                 << 
585         theEventInfo.transparent = true;       << 
586         return false;                          << 
587       }                                        << 
588     }                                             283     }
589                                                << 
590                                                   284 
591     // Randomly draw an impact parameter or us    285     // Randomly draw an impact parameter or use a fixed value, depending on the
592     // Config option                              286     // Config option
593     G4double impactParameter, phi;                287     G4double impactParameter, phi;
594     if(fixedImpactParameter<0.) {                 288     if(fixedImpactParameter<0.) {
595       impactParameter = maxImpactParameter * s    289       impactParameter = maxImpactParameter * std::sqrt(Random::shoot0());
596       phi = Random::shoot() * Math::twoPi;        290       phi = Random::shoot() * Math::twoPi;
597     } else {                                      291     } else {
598       impactParameter = fixedImpactParameter;     292       impactParameter = fixedImpactParameter;
599       phi = 0.;                                   293       phi = 0.;
600     }                                             294     }
601     INCL_DEBUG("Selected impact parameter: " <    295     INCL_DEBUG("Selected impact parameter: " << impactParameter << '\n');
602                                                   296 
603     // Fill in the event information              297     // Fill in the event information
604     theEventInfo.impactParameter = impactParam    298     theEventInfo.impactParameter = impactParameter;
605                                                   299 
606     const G4double effectiveImpactParameter =     300     const G4double effectiveImpactParameter = propagationModel->shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
607     if(effectiveImpactParameter < 0.) {           301     if(effectiveImpactParameter < 0.) {
608       // Fill in the event information            302       // Fill in the event information
609       theEventInfo.transparent = true;            303       theEventInfo.transparent = true;
                                                   >> 304 
610       return false;                               305       return false;
611     }                                             306     }
612                                                   307 
613     // Fill in the event information              308     // Fill in the event information
614     theEventInfo.transparent = false;             309     theEventInfo.transparent = false;
615     theEventInfo.effectiveImpactParameter = ef    310     theEventInfo.effectiveImpactParameter = effectiveImpactParameter;
616                                                   311 
617     return true;                                  312     return true;
618   }                                               313   }
619                                                   314 
620   void INCL::cascade() {                          315   void INCL::cascade() {
621     FinalState *finalState = new FinalState;      316     FinalState *finalState = new FinalState;
622                                                   317 
623     unsigned long loopCounter = 0;                318     unsigned long loopCounter = 0;
624     const unsigned long maxLoopCounter = 10000    319     const unsigned long maxLoopCounter = 10000000;
625     do {                                          320     do {
626       // Run book keeping actions that should     321       // Run book keeping actions that should take place before propagation:
627       cascadeAction->beforePropagationAction(p    322       cascadeAction->beforePropagationAction(propagationModel);
628                                                   323 
629       // Get the avatar with the smallest time    324       // Get the avatar with the smallest time and propagate particles
630       // to that point in time.                   325       // to that point in time.
631       IAvatar *avatar = propagationModel->prop    326       IAvatar *avatar = propagationModel->propagate(finalState);
632                                                   327 
633       finalState->reset();                        328       finalState->reset();
634                                                   329 
635       // Run book keeping actions that should     330       // Run book keeping actions that should take place after propagation:
636       cascadeAction->afterPropagationAction(pr    331       cascadeAction->afterPropagationAction(propagationModel, avatar);
637                                                   332 
638       if(avatar == 0) break; // No more avatar    333       if(avatar == 0) break; // No more avatars in the avatar list.
639                                                   334 
640       // Run book keeping actions that should     335       // Run book keeping actions that should take place before avatar:
641       cascadeAction->beforeAvatarAction(avatar    336       cascadeAction->beforeAvatarAction(avatar, nucleus);
642                                                   337 
643       // Channel is responsible for calculatin    338       // Channel is responsible for calculating the outcome of the
644       // selected avatar. There are different     339       // selected avatar. There are different kinds of channels. The
645       // class IChannel is, again, an abstract    340       // class IChannel is, again, an abstract interface that defines
646       // the externally observable behavior of    341       // the externally observable behavior of all interaction
647       // channels.                                342       // channels.
648       // The handling of the channel is transp    343       // The handling of the channel is transparent to the API.
649       // Final state tells what changed...        344       // Final state tells what changed...
650       avatar->fillFinalState(finalState);         345       avatar->fillFinalState(finalState);
                                                   >> 346 
651       // Run book keeping actions that should     347       // Run book keeping actions that should take place after avatar:
652       cascadeAction->afterAvatarAction(avatar,    348       cascadeAction->afterAvatarAction(avatar, nucleus, finalState);
653                                                   349 
654       // So now we must give this information     350       // So now we must give this information to the nucleus
655       nucleus->applyFinalState(finalState);       351       nucleus->applyFinalState(finalState);
656       // and now we are ready to process the n    352       // and now we are ready to process the next avatar!
657                                                   353 
658       delete avatar;                              354       delete avatar;
659                                                   355 
660       ++loopCounter;                              356       ++loopCounter;
661     } while(continueCascade() && loopCounter<m    357     } while(continueCascade() && loopCounter<maxLoopCounter); /* Loop checking, 10.07.2015, D.Mancusi */
662                                                << 358 
663     delete finalState;                            359     delete finalState;
664   }                                               360   }
665                                                   361 
666   void INCL::postCascade(const ParticleSpecies << 362   void INCL::postCascade() {
667     // Fill in the event information              363     // Fill in the event information
668     theEventInfo.stoppingTime = propagationMod    364     theEventInfo.stoppingTime = propagationModel->getCurrentTime();
669                                                   365 
670     // The event bias                          << 
671     theEventInfo.eventBias = (Double_t) Partic << 
672                                                << 
673     // Forced CN?                                 366     // Forced CN?
674     if(!(projectileSpecies.theType==antiProton << 367     if(nucleus->getTryCompoundNucleus()) {
675       if(nucleus->getTryCompoundNucleus()) {   << 368       INCL_DEBUG("Trying compound nucleus" << '\n');
676         INCL_DEBUG("Trying compound nucleus" < << 369       makeCompoundNucleus();
677         makeCompoundNucleus();                 << 370       theEventInfo.transparent = forceTransparent;
678         theEventInfo.transparent = forceTransp << 
679       // Global checks of conservation laws       371       // Global checks of conservation laws
680 #ifndef INCLXX_IN_GEANT4_MODE                     372 #ifndef INCLXX_IN_GEANT4_MODE
681       if(!theEventInfo.transparent) globalCons    373       if(!theEventInfo.transparent) globalConservationChecks(true);
682 #endif                                            374 #endif
683       return;                                     375       return;
684       }                                        << 
685     }                                             376     }
686                                                   377 
687     if(!(projectileSpecies.theType==antiProton << 378     theEventInfo.transparent = forceTransparent || nucleus->isEventTransparent();
688       theEventInfo.transparent = forceTranspar << 
689     }                                          << 
690                                                   379 
691     if(theEventInfo.transparent) {                380     if(theEventInfo.transparent) {
692       ProjectileRemnant * const projectileRemn    381       ProjectileRemnant * const projectileRemnant = nucleus->getProjectileRemnant();
693       if(projectileRemnant) {                     382       if(projectileRemnant) {
694         // Clear the incoming list (particles     383         // Clear the incoming list (particles will be deleted by the ProjectileRemnant)
695         nucleus->getStore()->clearIncoming();     384         nucleus->getStore()->clearIncoming();
696       } else {                                    385       } else {
697         // Delete particles in the incoming li    386         // Delete particles in the incoming list
698         nucleus->getStore()->deleteIncoming();    387         nucleus->getStore()->deleteIncoming();
699       }                                           388       }
700     } else {                                      389     } else {
701                                                << 
702       // Check if the nucleus contains strange << 
703       theEventInfo.sigmasInside = nucleus->con << 
704       theEventInfo.antikaonsInside = nucleus-> << 
705       theEventInfo.lambdasInside = nucleus->co << 
706       theEventInfo.kaonsInside = nucleus->cont << 
707                                                << 
708       // Capture antiKaons and Sigmas and prod << 
709       theEventInfo.absorbedStrangeParticle = n << 
710                                                << 
711       // Emit strange particles still inside t << 
712       nucleus->emitInsideStrangeParticles();   << 
713       theEventInfo.emitKaon = nucleus->emitIns << 
714                                                << 
715 #ifdef INCLXX_IN_GEANT4_MODE                   << 
716       theEventInfo.emitLambda = nucleus->emitI << 
717 #endif // INCLXX_IN_GEANT4_MODE                << 
718                                                << 
719       // Check if the nucleus contains deltas     390       // Check if the nucleus contains deltas
720       theEventInfo.deltasInside = nucleus->con    391       theEventInfo.deltasInside = nucleus->containsDeltas();
721                                                   392 
722       // Take care of any remaining deltas        393       // Take care of any remaining deltas
723       theEventInfo.forcedDeltasOutside = nucle    394       theEventInfo.forcedDeltasOutside = nucleus->decayOutgoingDeltas();
724       theEventInfo.forcedDeltasInside = nucleu    395       theEventInfo.forcedDeltasInside = nucleus->decayInsideDeltas();
725                                                   396 
726       // Take care of any remaining etas, omeg << 397     // Take care of any remaining etas and/or omegas
727       G4double timeThreshold=theConfig->getDec << 398 /*    if (theConfig->getDecayTimeThreshold() > 7.e-19) {
728       theEventInfo.forcedPionResonancesOutside << 399       theEventInfo.forcedPionResonancesOutside = nucleus->decayOutgoingPionResonances();
729       nucleus->decayOutgoingSigmaZero(timeThre << 400     }*/
730       nucleus->decayOutgoingNeutralKaon();     << 401     G4double timeThreshold=theConfig->getDecayTimeThreshold();
731                                                << 402     theEventInfo.forcedPionResonancesOutside = nucleus->decayOutgoingPionResonances(timeThreshold);
                                                   >> 403     
732       // Apply Coulomb distortion, if appropri    404       // Apply Coulomb distortion, if appropriate
733       // Note that this will apply Coulomb dis    405       // Note that this will apply Coulomb distortion also on pions emitted by
734       // unphysical remnants (see decayInsideD    406       // unphysical remnants (see decayInsideDeltas). This is at variance with
735       // what INCL4.6 does, but these events a    407       // what INCL4.6 does, but these events are (should be!) so rare that
736       // whatever we do doesn't (shouldn't!) m    408       // whatever we do doesn't (shouldn't!) make any noticeable difference.
737       CoulombDistortion::distortOut(nucleus->g    409       CoulombDistortion::distortOut(nucleus->getStore()->getOutgoingParticles(), nucleus);
738                                                   410 
739       // If the normal cascade predicted compl    411       // If the normal cascade predicted complete fusion, use the tabulated
740       // masses to compute the excitation ener    412       // masses to compute the excitation energy, the recoil, etc.
741       if(nucleus->getStore()->getOutgoingParti    413       if(nucleus->getStore()->getOutgoingParticles().size()==0
742          && (!nucleus->getProjectileRemnant()     414          && (!nucleus->getProjectileRemnant()
743              || nucleus->getProjectileRemnant(    415              || nucleus->getProjectileRemnant()->getParticles().size()==0)) {
744                                                   416 
745         INCL_DEBUG("Cascade resulted in comple    417         INCL_DEBUG("Cascade resulted in complete fusion, using realistic fusion kinematics" << '\n');
746                                                   418 
747         nucleus->useFusionKinematics();           419         nucleus->useFusionKinematics();
748                                                   420 
749         if(nucleus->getExcitationEnergy()<0.)     421         if(nucleus->getExcitationEnergy()<0.) {
750           // Complete fusion is energetically     422           // Complete fusion is energetically impossible, return a transparent
751           INCL_WARN("Complete-fusion kinematic    423           INCL_WARN("Complete-fusion kinematics yields negative excitation energy, returning a transparent!" << '\n');
752           theEventInfo.transparent = true;        424           theEventInfo.transparent = true;
753           return;                                 425           return;
754         }                                         426         }
755                                                   427 
756       } else { // Normal cascade here             428       } else { // Normal cascade here
757                                                   429 
758         // Set the excitation energy              430         // Set the excitation energy
759         nucleus->setExcitationEnergy(nucleus->    431         nucleus->setExcitationEnergy(nucleus->computeExcitationEnergy());
760                                                   432 
761         // Make a projectile pre-fragment out     433         // Make a projectile pre-fragment out of the geometrical and dynamical
762         // spectators                             434         // spectators
763         theEventInfo.nUnmergedSpectators = mak    435         theEventInfo.nUnmergedSpectators = makeProjectileRemnant();
764                                                   436 
765         // Compute recoil momentum, energy and    437         // Compute recoil momentum, energy and spin of the nucleus
766         if(nucleus->getA()==1 && minRemnantSiz    438         if(nucleus->getA()==1 && minRemnantSize>1) {
767           INCL_ERROR("Computing one-nucleon re    439           INCL_ERROR("Computing one-nucleon recoil kinematics. We should never be here nowadays, cascade should stop earlier than this." << '\n');
768         }                                         440         }
769         nucleus->computeRecoilKinematics();       441         nucleus->computeRecoilKinematics();
770                                                   442 
771 #ifndef INCLXX_IN_GEANT4_MODE                     443 #ifndef INCLXX_IN_GEANT4_MODE
772         // Global checks of conservation laws     444         // Global checks of conservation laws
773         globalConservationChecks(false);          445         globalConservationChecks(false);
774 #endif                                            446 #endif
775                                                   447 
776         // Make room for the remnant recoil by    448         // Make room for the remnant recoil by rescaling the energies of the
777         // outgoing particles.                    449         // outgoing particles.
778         if(nucleus->hasRemnant()) rescaleOutgo    450         if(nucleus->hasRemnant()) rescaleOutgoingForRecoil();
779                                                   451 
780       }                                           452       }
781                                                   453 
782       // Cluster decay                            454       // Cluster decay
783       theEventInfo.clusterDecay = nucleus->dec << 455       theEventInfo.clusterDecay = nucleus->decayOutgoingClusters() | nucleus->decayMe();
784                                                   456 
785 #ifndef INCLXX_IN_GEANT4_MODE                     457 #ifndef INCLXX_IN_GEANT4_MODE
786       // Global checks of conservation laws       458       // Global checks of conservation laws
787       globalConservationChecks(true);             459       globalConservationChecks(true);
788 #endif                                            460 #endif
789                                                   461 
790       // Fill the EventInfo structure             462       // Fill the EventInfo structure
791       nucleus->fillEventInfo(&theEventInfo);      463       nucleus->fillEventInfo(&theEventInfo);
792                                                   464 
793     }                                             465     }
794   }                                               466   }
795                                                   467 
796   void INCL::makeCompoundNucleus() {              468   void INCL::makeCompoundNucleus() {
797     // If this is not a nucleus-nucleus collis    469     // If this is not a nucleus-nucleus collision, don't attempt to make a
798     // compound nucleus.                          470     // compound nucleus.
799     //                                            471     //
800     // Yes, even nucleon-nucleus collisions ca    472     // Yes, even nucleon-nucleus collisions can lead to particles entering
801     // below the Fermi level. Take e.g. 1-MeV     473     // below the Fermi level. Take e.g. 1-MeV p + He4.
802     if(!nucleus->isNucleusNucleusCollision())     474     if(!nucleus->isNucleusNucleusCollision()) {
803       forceTransparent = true;                    475       forceTransparent = true;
804       return;                                     476       return;
805     }                                             477     }
806                                                   478 
807     // Reset the internal Nucleus variables       479     // Reset the internal Nucleus variables
808     nucleus->getStore()->clearIncoming();         480     nucleus->getStore()->clearIncoming();
809     nucleus->getStore()->clearOutgoing();         481     nucleus->getStore()->clearOutgoing();
810     nucleus->getProjectileRemnant()->reset();     482     nucleus->getProjectileRemnant()->reset();
811     nucleus->setA(theEventInfo.At);               483     nucleus->setA(theEventInfo.At);
812     nucleus->setZ(theEventInfo.Zt);               484     nucleus->setZ(theEventInfo.Zt);
813                                                   485 
814     // CN kinematical variables                   486     // CN kinematical variables
815     // Note: the CN orbital angular momentum i    487     // Note: the CN orbital angular momentum is neglected in what follows. We
816     // should actually take it into account!      488     // should actually take it into account!
817     ThreeVector theCNMomentum = nucleus->getIn    489     ThreeVector theCNMomentum = nucleus->getIncomingMomentum();
818     ThreeVector theCNSpin = nucleus->getIncomi    490     ThreeVector theCNSpin = nucleus->getIncomingAngularMomentum();
819     const G4double theTargetMass = ParticleTab << 491     const G4double theTargetMass = ParticleTable::getTableMass(theEventInfo.At, theEventInfo.Zt);
820     G4int theCNA=theEventInfo.At, theCNZ=theEv << 492     G4int theCNA=theEventInfo.At, theCNZ=theEventInfo.Zt;
821     Cluster * const theProjectileRemnant = nuc    493     Cluster * const theProjectileRemnant = nucleus->getProjectileRemnant();
822     G4double theCNEnergy = theTargetMass + the    494     G4double theCNEnergy = theTargetMass + theProjectileRemnant->getEnergy();
823                                                   495 
824     // Loop over the potential participants       496     // Loop over the potential participants
825     ParticleList const &initialProjectileCompo    497     ParticleList const &initialProjectileComponents = theProjectileRemnant->getParticles();
826     std::vector<Particle *> shuffledComponents    498     std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
827     // Shuffle the list of potential participa    499     // Shuffle the list of potential participants
828     std::shuffle(shuffledComponents.begin(), s << 500     std::random_shuffle(shuffledComponents.begin(), shuffledComponents.end(), Random::getAdapter());
829                                                   501 
830     G4bool success = true;                        502     G4bool success = true;
831     G4bool atLeastOneNucleonEntering = false;     503     G4bool atLeastOneNucleonEntering = false;
832     for(std::vector<Particle*>::const_iterator    504     for(std::vector<Particle*>::const_iterator p=shuffledComponents.begin(), e=shuffledComponents.end(); p!=e; ++p) {
833       // Skip particles that miss the interact    505       // Skip particles that miss the interaction distance
834       Intersection intersectionInteractionDist    506       Intersection intersectionInteractionDistance(IntersectionFactory::getEarlierTrajectoryIntersection(
835             (*p)->getPosition(),                  507             (*p)->getPosition(),
836             (*p)->getPropagationVelocity(),       508             (*p)->getPropagationVelocity(),
837             maxInteractionDistance));             509             maxInteractionDistance));
838       if(!intersectionInteractionDistance.exis    510       if(!intersectionInteractionDistance.exists)
839         continue;                                 511         continue;
840                                                   512 
841       // Build an entry avatar for this nucleo    513       // Build an entry avatar for this nucleon
842       atLeastOneNucleonEntering = true;           514       atLeastOneNucleonEntering = true;
843       ParticleEntryAvatar *theAvatar = new Par    515       ParticleEntryAvatar *theAvatar = new ParticleEntryAvatar(0.0, nucleus, *p);
844       nucleus->getStore()->addParticleEntryAva    516       nucleus->getStore()->addParticleEntryAvatar(theAvatar);
845       FinalState *fs = theAvatar->getFinalStat    517       FinalState *fs = theAvatar->getFinalState();
846       nucleus->applyFinalState(fs);               518       nucleus->applyFinalState(fs);
847       FinalStateValidity validity = fs->getVal    519       FinalStateValidity validity = fs->getValidity();
848       delete fs;                                  520       delete fs;
849       switch(validity) {                          521       switch(validity) {
850         case ValidFS:                             522         case ValidFS:
851         case ParticleBelowFermiFS:                523         case ParticleBelowFermiFS:
852         case ParticleBelowZeroFS:                 524         case ParticleBelowZeroFS:
853           // Add the particle to the CN           525           // Add the particle to the CN
854           theCNA++;                               526           theCNA++;
855           theCNZ += (*p)->getZ();                 527           theCNZ += (*p)->getZ();
856           theCNS += (*p)->getS();              << 
857           break;                                  528           break;
858         case PauliBlockedFS:                      529         case PauliBlockedFS:
859         case NoEnergyConservationFS:              530         case NoEnergyConservationFS:
860         default:                                  531         default:
861           success = false;                        532           success = false;
862           break;                                  533           break;
863       }                                           534       }
864     }                                             535     }
865                                                   536 
866     if(!success || !atLeastOneNucleonEntering)    537     if(!success || !atLeastOneNucleonEntering) {
867       INCL_DEBUG("No nucleon entering in force    538       INCL_DEBUG("No nucleon entering in forced CN, forcing a transparent" << '\n');
868       forceTransparent = true;                    539       forceTransparent = true;
869       return;                                     540       return;
870     }                                             541     }
871                                                   542 
872 // assert(theCNA==nucleus->getA());               543 // assert(theCNA==nucleus->getA());
873 // assert(theCNA<=theEventInfo.At+theEventInfo    544 // assert(theCNA<=theEventInfo.At+theEventInfo.Ap);
874 // assert(theCNZ<=theEventInfo.Zt+theEventInfo    545 // assert(theCNZ<=theEventInfo.Zt+theEventInfo.Zp);
875 // assert(theCNS>=theEventInfo.St+theEventInfo << 
876                                                   546 
877     // Update the kinematics of the CN            547     // Update the kinematics of the CN
878     theCNEnergy -= theProjectileRemnant->getEn    548     theCNEnergy -= theProjectileRemnant->getEnergy();
879     theCNMomentum -= theProjectileRemnant->get    549     theCNMomentum -= theProjectileRemnant->getMomentum();
880                                                   550 
881     // Deal with the projectile remnant           551     // Deal with the projectile remnant
882     nucleus->finalizeProjectileRemnant(propaga    552     nucleus->finalizeProjectileRemnant(propagationModel->getCurrentTime());
883                                                   553 
884     // Subtract the angular momentum of the pr    554     // Subtract the angular momentum of the projectile remnant
885 // assert(nucleus->getStore()->getOutgoingPart    555 // assert(nucleus->getStore()->getOutgoingParticles().empty());
886     theCNSpin -= theProjectileRemnant->getAngu    556     theCNSpin -= theProjectileRemnant->getAngularMomentum();
887                                                   557 
888     // Compute the excitation energy of the CN    558     // Compute the excitation energy of the CN
889     const G4double theCNMass = ParticleTable:: << 559     const G4double theCNMass = ParticleTable::getTableMass(theCNA,theCNZ);
890     const G4double theCNInvariantMassSquared =    560     const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
891     if(theCNInvariantMassSquared<0.) {            561     if(theCNInvariantMassSquared<0.) {
892       // Negative invariant mass squared, retu    562       // Negative invariant mass squared, return a transparent
893       forceTransparent = true;                    563       forceTransparent = true;
894       return;                                     564       return;
895     }                                             565     }
896     const G4double theCNExcitationEnergy = std    566     const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
897     if(theCNExcitationEnergy<0.) {                567     if(theCNExcitationEnergy<0.) {
898       // Negative excitation energy, return a     568       // Negative excitation energy, return a transparent
899       INCL_DEBUG("CN excitation energy is nega    569       INCL_DEBUG("CN excitation energy is negative, forcing a transparent" << '\n'
900             << "  theCNA = " << theCNA << '\n'    570             << "  theCNA = " << theCNA << '\n'
901             << "  theCNZ = " << theCNZ << '\n'    571             << "  theCNZ = " << theCNZ << '\n'
902             << "  theCNS = " << theCNS << '\n' << 
903             << "  theCNEnergy = " << theCNEner    572             << "  theCNEnergy = " << theCNEnergy << '\n'
904             << "  theCNMomentum = (" << theCNM    573             << "  theCNMomentum = (" << theCNMomentum.getX() << ", "<< theCNMomentum.getY() << ", "  << theCNMomentum.getZ() << ")" << '\n'
905             << "  theCNExcitationEnergy = " <<    574             << "  theCNExcitationEnergy = " << theCNExcitationEnergy << '\n'
906             << "  theCNSpin = (" << theCNSpin.    575             << "  theCNSpin = (" << theCNSpin.getX() << ", "<< theCNSpin.getY() << ", "  << theCNSpin.getZ() << ")" << '\n'
907             );                                    576             );
908       forceTransparent = true;                    577       forceTransparent = true;
909       return;                                     578       return;
910     } else {                                      579     } else {
911       // Positive excitation energy, can make     580       // Positive excitation energy, can make a CN
912       INCL_DEBUG("CN excitation energy is posi    581       INCL_DEBUG("CN excitation energy is positive, forcing a CN" << '\n'
913             << "  theCNA = " << theCNA << '\n'    582             << "  theCNA = " << theCNA << '\n'
914             << "  theCNZ = " << theCNZ << '\n'    583             << "  theCNZ = " << theCNZ << '\n'
915             << "  theCNS = " << theCNS << '\n' << 
916             << "  theCNEnergy = " << theCNEner    584             << "  theCNEnergy = " << theCNEnergy << '\n'
917             << "  theCNMomentum = (" << theCNM    585             << "  theCNMomentum = (" << theCNMomentum.getX() << ", "<< theCNMomentum.getY() << ", "  << theCNMomentum.getZ() << ")" << '\n'
918             << "  theCNExcitationEnergy = " <<    586             << "  theCNExcitationEnergy = " << theCNExcitationEnergy << '\n'
919             << "  theCNSpin = (" << theCNSpin.    587             << "  theCNSpin = (" << theCNSpin.getX() << ", "<< theCNSpin.getY() << ", "  << theCNSpin.getZ() << ")" << '\n'
920             );                                    588             );
921       nucleus->setA(theCNA);                      589       nucleus->setA(theCNA);
922       nucleus->setZ(theCNZ);                      590       nucleus->setZ(theCNZ);
923       nucleus->setS(theCNS);                   << 
924       nucleus->setMomentum(theCNMomentum);        591       nucleus->setMomentum(theCNMomentum);
925       nucleus->setEnergy(theCNEnergy);            592       nucleus->setEnergy(theCNEnergy);
926       nucleus->setExcitationEnergy(theCNExcita    593       nucleus->setExcitationEnergy(theCNExcitationEnergy);
927       nucleus->setMass(theCNMass+theCNExcitati    594       nucleus->setMass(theCNMass+theCNExcitationEnergy);
928       nucleus->setSpin(theCNSpin); // neglects    595       nucleus->setSpin(theCNSpin); // neglects any orbital angular momentum of the CN
929                                                   596 
930       // Take care of any remaining deltas        597       // Take care of any remaining deltas
931       theEventInfo.forcedDeltasOutside = nucle    598       theEventInfo.forcedDeltasOutside = nucleus->decayOutgoingDeltas();
932                                                   599 
933       // Take care of any remaining etas and/o << 600     // Take care of any remaining etas and/or omegas
934       G4double timeThreshold=theConfig->getDec << 601     G4double timeThreshold=theConfig->getDecayTimeThreshold();
935       theEventInfo.forcedPionResonancesOutside    602       theEventInfo.forcedPionResonancesOutside = nucleus->decayOutgoingPionResonances(timeThreshold);
936                                                << 603     
937       // Take care of any remaining Kaons      << 
938       theEventInfo.emitKaon = nucleus->emitIns << 
939                                                << 
940       // Cluster decay                            604       // Cluster decay
941       theEventInfo.clusterDecay = nucleus->dec << 605       theEventInfo.clusterDecay = nucleus->decayOutgoingClusters() | nucleus->decayMe();
942                                                   606 
943       // Fill the EventInfo structure             607       // Fill the EventInfo structure
944       nucleus->fillEventInfo(&theEventInfo);      608       nucleus->fillEventInfo(&theEventInfo);
945     }                                             609     }
946   }                                               610   }
947                                                   611 
948   void INCL::rescaleOutgoingForRecoil() {         612   void INCL::rescaleOutgoingForRecoil() {
949     RecoilCMFunctor theRecoilFunctor(nucleus,     613     RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
950                                                   614 
951     // Apply the root-finding algorithm           615     // Apply the root-finding algorithm
952     const RootFinder::Solution theSolution = R    616     const RootFinder::Solution theSolution = RootFinder::solve(&theRecoilFunctor, 1.0);
953     if(theSolution.success) {                     617     if(theSolution.success) {
954       theRecoilFunctor(theSolution.x); // Appl    618       theRecoilFunctor(theSolution.x); // Apply the solution
955     } else {                                      619     } else {
956       INCL_WARN("Couldn't accommodate remnant     620       INCL_WARN("Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." << '\n');
957     }                                             621     }
                                                   >> 622 
958   }                                               623   }
959                                                   624 
960 #ifndef INCLXX_IN_GEANT4_MODE                     625 #ifndef INCLXX_IN_GEANT4_MODE
961   void INCL::globalConservationChecks(G4bool a    626   void INCL::globalConservationChecks(G4bool afterRecoil) {
962     Nucleus::ConservationBalance theBalance =     627     Nucleus::ConservationBalance theBalance = nucleus->getConservationBalance(theEventInfo,afterRecoil);
963                                                   628 
964     // Global conservation checks                 629     // Global conservation checks
965     const G4double pLongBalance = theBalance.m    630     const G4double pLongBalance = theBalance.momentum.getZ();
966     const G4double pTransBalance = theBalance.    631     const G4double pTransBalance = theBalance.momentum.perp();
967     if(theBalance.Z != 0) {                       632     if(theBalance.Z != 0) {
968       INCL_ERROR("Violation of charge conserva << 633       INCL_ERROR("Violation of charge conservation! ZBalance = " << theBalance.Z << '\n');
969     }                                             634     }
970     if(theBalance.A != 0) {                       635     if(theBalance.A != 0) {
971       INCL_ERROR("Violation of baryon-number c << 636       INCL_ERROR("Violation of baryon-number conservation! ABalance = " << theBalance.A << '\n');
972     }                                          << 
973     if(theBalance.S != 0) {                    << 
974       INCL_ERROR("Violation of strange-number  << 
975     }                                             637     }
976     G4double EThreshold, pLongThreshold, pTran    638     G4double EThreshold, pLongThreshold, pTransThreshold;
977     if(afterRecoil) {                             639     if(afterRecoil) {
978       // Less stringent checks after accommoda    640       // Less stringent checks after accommodating recoil
979       EThreshold = 10.; // MeV                    641       EThreshold = 10.; // MeV
980       pLongThreshold = 1.; // MeV/c               642       pLongThreshold = 1.; // MeV/c
981       pTransThreshold = 1.; // MeV/c              643       pTransThreshold = 1.; // MeV/c
982     } else {                                      644     } else {
983       // More stringent checks before accommod    645       // More stringent checks before accommodating recoil
984       EThreshold = 0.1; // MeV                    646       EThreshold = 0.1; // MeV
985       pLongThreshold = 0.1; // MeV/c              647       pLongThreshold = 0.1; // MeV/c
986       pTransThreshold = 0.1; // MeV/c             648       pTransThreshold = 0.1; // MeV/c
987     }                                             649     }
988     if(std::abs(theBalance.energy)>EThreshold)    650     if(std::abs(theBalance.energy)>EThreshold) {
989       INCL_WARN("Violation of energy conservat << 651       INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
990     }                                             652     }
991     if(std::abs(pLongBalance)>pLongThreshold)     653     if(std::abs(pLongBalance)>pLongThreshold) {
992       INCL_WARN("Violation of longitudinal mom    654       INCL_WARN("Violation of longitudinal momentum conservation > " << pLongThreshold << " MeV/c. pLongBalance = " << pLongBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
993     }                                             655     }
994     if(std::abs(pTransBalance)>pTransThreshold    656     if(std::abs(pTransBalance)>pTransThreshold) {
995       INCL_WARN("Violation of transverse momen    657       INCL_WARN("Violation of transverse momentum conservation > " << pTransThreshold << " MeV/c. pTransBalance = " << pTransBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
996     }                                             658     }
997                                                   659 
998     // Feed the EventInfo variables               660     // Feed the EventInfo variables
999     theEventInfo.EBalance = theBalance.energy;    661     theEventInfo.EBalance = theBalance.energy;
1000     theEventInfo.pLongBalance = pLongBalance;    662     theEventInfo.pLongBalance = pLongBalance;
1001     theEventInfo.pTransBalance = pTransBalanc    663     theEventInfo.pTransBalance = pTransBalance;
1002   }                                              664   }
1003 #endif                                           665 #endif
1004                                                  666 
1005   G4bool INCL::continueCascade() {               667   G4bool INCL::continueCascade() {
1006     // Stop if we have passed the stopping ti    668     // Stop if we have passed the stopping time
1007     if(propagationModel->getCurrentTime() > p    669     if(propagationModel->getCurrentTime() > propagationModel->getStoppingTime()) {
1008       INCL_DEBUG("Cascade time (" << propagat    670       INCL_DEBUG("Cascade time (" << propagationModel->getCurrentTime()
1009           << ") exceeded stopping time (" <<     671           << ") exceeded stopping time (" << propagationModel->getStoppingTime()
1010           << "), stopping cascade" << '\n');     672           << "), stopping cascade" << '\n');
1011       return false;                              673       return false;
1012     }                                            674     }
1013     // Stop if there are no participants and     675     // Stop if there are no participants and no pions inside the nucleus
1014     if(nucleus->getStore()->getBook().getCasc    676     if(nucleus->getStore()->getBook().getCascading()==0 &&
1015         nucleus->getStore()->getIncomingParti    677         nucleus->getStore()->getIncomingParticles().empty()) {
1016       INCL_DEBUG("No participants in the nucl    678       INCL_DEBUG("No participants in the nucleus and no incoming particles left, stopping cascade" << '\n');
1017       return false;                              679       return false;
1018     }                                            680     }
1019     // Stop if the remnant is smaller than mi    681     // Stop if the remnant is smaller than minRemnantSize
1020     if(nucleus->getA() <= minRemnantSize) {      682     if(nucleus->getA() <= minRemnantSize) {
1021       INCL_DEBUG("Remnant size (" << nucleus-    683       INCL_DEBUG("Remnant size (" << nucleus->getA()
1022           << ") smaller than or equal to mini    684           << ") smaller than or equal to minimum (" << minRemnantSize
1023           << "), stopping cascade" << '\n');     685           << "), stopping cascade" << '\n');
1024       return false;                              686       return false;
1025     }                                            687     }
1026     // Stop if we have to try and make a comp    688     // Stop if we have to try and make a compound nucleus or if we have to
1027     // force a transparent                       689     // force a transparent
1028     if(nucleus->getTryCompoundNucleus()) {       690     if(nucleus->getTryCompoundNucleus()) {
1029       INCL_DEBUG("Trying to make a compound n    691       INCL_DEBUG("Trying to make a compound nucleus, stopping cascade" << '\n');
1030       return false;                              692       return false;
1031     }                                            693     }
1032                                                  694 
1033     return true;                                 695     return true;
1034   }                                              696   }
1035                                                  697 
1036   void INCL::finalizeGlobalInfo(Random::SeedV    698   void INCL::finalizeGlobalInfo(Random::SeedVector const &initialSeeds) {
1037     const G4double normalisationFactor = theG    699     const G4double normalisationFactor = theGlobalInfo.geometricCrossSection /
1038       ((G4double) theGlobalInfo.nShots);         700       ((G4double) theGlobalInfo.nShots);
1039     theGlobalInfo.nucleonAbsorptionCrossSecti    701     theGlobalInfo.nucleonAbsorptionCrossSection = normalisationFactor *
1040       ((G4double) theGlobalInfo.nNucleonAbsor    702       ((G4double) theGlobalInfo.nNucleonAbsorptions);
1041     theGlobalInfo.pionAbsorptionCrossSection     703     theGlobalInfo.pionAbsorptionCrossSection = normalisationFactor *
1042       ((G4double) theGlobalInfo.nPionAbsorpti    704       ((G4double) theGlobalInfo.nPionAbsorptions);
1043     theGlobalInfo.reactionCrossSection = norm    705     theGlobalInfo.reactionCrossSection = normalisationFactor *
1044       ((G4double) (theGlobalInfo.nShots - the    706       ((G4double) (theGlobalInfo.nShots - theGlobalInfo.nTransparents));
1045     theGlobalInfo.errorReactionCrossSection =    707     theGlobalInfo.errorReactionCrossSection = normalisationFactor *
1046       std::sqrt((G4double) (theGlobalInfo.nSh    708       std::sqrt((G4double) (theGlobalInfo.nShots - theGlobalInfo.nTransparents));
1047     theGlobalInfo.forcedCNCrossSection = norm    709     theGlobalInfo.forcedCNCrossSection = normalisationFactor *
1048       ((G4double) theGlobalInfo.nForcedCompou    710       ((G4double) theGlobalInfo.nForcedCompoundNucleus);
1049     theGlobalInfo.errorForcedCNCrossSection =    711     theGlobalInfo.errorForcedCNCrossSection = normalisationFactor *
1050       std::sqrt((G4double) (theGlobalInfo.nFo    712       std::sqrt((G4double) (theGlobalInfo.nForcedCompoundNucleus));
1051     theGlobalInfo.completeFusionCrossSection     713     theGlobalInfo.completeFusionCrossSection = normalisationFactor *
1052       ((G4double) theGlobalInfo.nCompleteFusi    714       ((G4double) theGlobalInfo.nCompleteFusion);
1053     theGlobalInfo.errorCompleteFusionCrossSec    715     theGlobalInfo.errorCompleteFusionCrossSection = normalisationFactor *
1054       std::sqrt((G4double) (theGlobalInfo.nCo    716       std::sqrt((G4double) (theGlobalInfo.nCompleteFusion));
1055     theGlobalInfo.energyViolationInteractionC    717     theGlobalInfo.energyViolationInteractionCrossSection = normalisationFactor *
1056       ((G4double) theGlobalInfo.nEnergyViolat    718       ((G4double) theGlobalInfo.nEnergyViolationInteraction);
1057                                                  719 
1058     theGlobalInfo.initialRandomSeeds.assign(i    720     theGlobalInfo.initialRandomSeeds.assign(initialSeeds.begin(), initialSeeds.end());
1059                                                  721 
1060     Random::SeedVector theSeeds = Random::get    722     Random::SeedVector theSeeds = Random::getSeeds();
1061     theGlobalInfo.finalRandomSeeds.assign(the    723     theGlobalInfo.finalRandomSeeds.assign(theSeeds.begin(), theSeeds.end());
1062   }                                              724   }
1063                                                  725 
1064   G4int INCL::makeProjectileRemnant() {          726   G4int INCL::makeProjectileRemnant() {
1065     // Do nothing if this is not a nucleus-nu    727     // Do nothing if this is not a nucleus-nucleus reaction
1066     if(!nucleus->getProjectileRemnant())         728     if(!nucleus->getProjectileRemnant())
1067       return 0;                                  729       return 0;
1068                                                  730 
1069     // Get the spectators (geometrical+dynami    731     // Get the spectators (geometrical+dynamical) from the Store
1070     ParticleList geomSpectators(nucleus->getP    732     ParticleList geomSpectators(nucleus->getProjectileRemnant()->getParticles());
1071     ParticleList dynSpectators(nucleus->getSt    733     ParticleList dynSpectators(nucleus->getStore()->extractDynamicalSpectators());
1072                                                  734 
1073     G4int nUnmergedSpectators = 0;               735     G4int nUnmergedSpectators = 0;
1074                                                  736 
1075     // If there are no spectators, do nothing    737     // If there are no spectators, do nothing
1076     if(dynSpectators.empty() && geomSpectator    738     if(dynSpectators.empty() && geomSpectators.empty()) {
1077       return 0;                                  739       return 0;
1078     } else if(dynSpectators.size()==1 && geom    740     } else if(dynSpectators.size()==1 && geomSpectators.empty()) {
1079       // No geometrical spectators, one dynam    741       // No geometrical spectators, one dynamical spectator
1080       // Just put it back in the outgoing lis    742       // Just put it back in the outgoing list
1081       nucleus->getStore()->addToOutgoing(dynS    743       nucleus->getStore()->addToOutgoing(dynSpectators.front());
1082     } else {                                     744     } else {
1083       // Make a cluster out of the geometrica    745       // Make a cluster out of the geometrical spectators
1084       ProjectileRemnant *theProjectileRemnant    746       ProjectileRemnant *theProjectileRemnant = nucleus->getProjectileRemnant();
1085                                                  747 
1086       // Add the dynamical spectators to the     748       // Add the dynamical spectators to the bunch
1087       ParticleList rejected = theProjectileRe    749       ParticleList rejected = theProjectileRemnant->addAllDynamicalSpectators(dynSpectators);
1088       // Put back the rejected spectators int    750       // Put back the rejected spectators into the outgoing list
1089       nUnmergedSpectators = (G4int)rejected.s << 751       nUnmergedSpectators = rejected.size();
1090       nucleus->getStore()->addToOutgoing(reje    752       nucleus->getStore()->addToOutgoing(rejected);
1091                                                  753 
1092       // Deal with the projectile remnant        754       // Deal with the projectile remnant
1093       nucleus->finalizeProjectileRemnant(prop    755       nucleus->finalizeProjectileRemnant(propagationModel->getCurrentTime());
1094                                                  756 
1095     }                                            757     }
1096                                                  758 
1097     return nUnmergedSpectators;                  759     return nUnmergedSpectators;
1098   }                                              760   }
1099                                                  761 
1100   void INCL::initMaxInteractionDistance(Parti    762   void INCL::initMaxInteractionDistance(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
1101     if(projectileSpecies.theType != Composite    763     if(projectileSpecies.theType != Composite) {
1102       maxInteractionDistance = 0.;               764       maxInteractionDistance = 0.;
1103       return;                                    765       return;
1104     }                                            766     }
1105                                                  767 
1106     const G4double r0 = std::max(ParticleTabl    768     const G4double r0 = std::max(ParticleTable::getNuclearRadius(Proton, theA, theZ),
1107                                ParticleTable:    769                                ParticleTable::getNuclearRadius(Neutron, theA, theZ));
1108                                                  770 
1109     const G4double theNNDistance = CrossSecti    771     const G4double theNNDistance = CrossSections::interactionDistanceNN(projectileSpecies, kineticEnergy);
1110     maxInteractionDistance = r0 + theNNDistan    772     maxInteractionDistance = r0 + theNNDistance;
1111     INCL_DEBUG("Initialised interaction dista    773     INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
1112           << "    theNNDistance = " << theNND    774           << "    theNNDistance = " << theNNDistance << '\n'
1113           << "    maxInteractionDistance = "     775           << "    maxInteractionDistance = " << maxInteractionDistance << '\n');
1114   }                                              776   }
1115                                                  777 
1116   void INCL::initUniverseRadius(ParticleSpeci    778   void INCL::initUniverseRadius(ParticleSpecies const &p, const G4double kineticEnergy, const G4int A, const G4int Z) {
1117     G4double rMax = 0.0;                         779     G4double rMax = 0.0;
1118     if(A==0) {                                   780     if(A==0) {
1119       IsotopicDistribution const &anIsotopicD    781       IsotopicDistribution const &anIsotopicDistribution =
1120         ParticleTable::getNaturalIsotopicDist    782         ParticleTable::getNaturalIsotopicDistribution(Z);
1121       IsotopeVector theIsotopes = anIsotopicD    783       IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
1122       for(IsotopeIter i=theIsotopes.begin(),     784       for(IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
1123         const G4double pMaximumRadius = Parti    785         const G4double pMaximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, i->theA, Z);
1124         const G4double nMaximumRadius = Parti    786         const G4double nMaximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, i->theA, Z);
1125         const G4double maximumRadius = std::m << 787         const G4double maximumRadius = std::min(pMaximumRadius, nMaximumRadius);
1126         rMax = std::max(maximumRadius, rMax);    788         rMax = std::max(maximumRadius, rMax);
1127       }                                          789       }
1128     } else {                                     790     } else {
1129       const G4double pMaximumRadius = Particl    791       const G4double pMaximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, A, Z);
1130       const G4double nMaximumRadius = Particl    792       const G4double nMaximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, A, Z);
1131       const G4double maximumRadius = std::max << 793       rMax = std::min(pMaximumRadius, nMaximumRadius);
1132       rMax = std::max(maximumRadius, rMax);   << 
1133     }                                            794     }
1134     if(p.theType==Composite || p.theType==Pro    795     if(p.theType==Composite || p.theType==Proton || p.theType==Neutron) {
1135       const G4double interactionDistanceNN =     796       const G4double interactionDistanceNN = CrossSections::interactionDistanceNN(p, kineticEnergy);
1136       maxUniverseRadius = rMax + interactionD    797       maxUniverseRadius = rMax + interactionDistanceNN;
1137     } else if(p.theType==PiPlus                  798     } else if(p.theType==PiPlus
1138         || p.theType==PiZero                     799         || p.theType==PiZero
1139         || p.theType==PiMinus) {                 800         || p.theType==PiMinus) {
1140       const G4double interactionDistancePiN =    801       const G4double interactionDistancePiN = CrossSections::interactionDistancePiN(kineticEnergy);
1141       maxUniverseRadius = rMax + interactionD    802       maxUniverseRadius = rMax + interactionDistancePiN;
1142     } else if(p.theType==KPlus                << 
1143         || p.theType==KZero) {                << 
1144       const G4double interactionDistanceKN =  << 
1145       maxUniverseRadius = rMax + interactionD << 
1146     } else if(p.theType==KZeroBar             << 
1147         || p.theType==KMinus) {               << 
1148       const G4double interactionDistanceKbarN << 
1149       maxUniverseRadius = rMax + interactionD << 
1150     } else if(p.theType==Lambda               << 
1151         ||p.theType==SigmaPlus                << 
1152         || p.theType==SigmaZero               << 
1153         || p.theType==SigmaMinus) {           << 
1154       const G4double interactionDistanceYN =  << 
1155       maxUniverseRadius = rMax + interactionD << 
1156     }                                         << 
1157       else if(p.theType==antiProton) {        << 
1158       maxUniverseRadius = rMax;               << 
1159     }                                            803     }
1160     INCL_DEBUG("Initialised universe radius:     804     INCL_DEBUG("Initialised universe radius: " << maxUniverseRadius << '\n');
1161   }                                              805   }
1162                                                  806 
1163                                               << 
1164   G4double INCL::initUniverseRadiusForAntipro << 
1165     G4double rMax = 0.0;                      << 
1166     if(A==0) {                                << 
1167       IsotopicDistribution const &anIsotopicD << 
1168         ParticleTable::getNaturalIsotopicDist << 
1169       IsotopeVector theIsotopes = anIsotopicD << 
1170       for(IsotopeIter i=theIsotopes.begin(),  << 
1171         const G4double pMaximumRadius = Parti << 
1172         const G4double nMaximumRadius = Parti << 
1173         const G4double maximumRadius = std::m << 
1174         rMax = std::max(maximumRadius, rMax); << 
1175       }                                       << 
1176     } else {                                  << 
1177       const G4double pMaximumRadius = Particl << 
1178       const G4double nMaximumRadius = Particl << 
1179       const G4double maximumRadius = std::max << 
1180       rMax = std::max(maximumRadius, rMax);   << 
1181     }                                         << 
1182     return rMax;                              << 
1183     }                                         << 
1184                                               << 
1185                                               << 
1186   void INCL::updateGlobalInfo() {                807   void INCL::updateGlobalInfo() {
1187     // Increment the global counter for the n    808     // Increment the global counter for the number of shots
1188     theGlobalInfo.nShots++;                      809     theGlobalInfo.nShots++;
1189                                                  810 
1190     if(theEventInfo.transparent) {               811     if(theEventInfo.transparent) {
1191       // Increment the global counter for the    812       // Increment the global counter for the number of transparents
1192       theGlobalInfo.nTransparents++;             813       theGlobalInfo.nTransparents++;
1193       // Increment the global counter for the    814       // Increment the global counter for the number of forced transparents
1194       if(forceTransparent)                       815       if(forceTransparent)
1195         theGlobalInfo.nForcedTransparents++;     816         theGlobalInfo.nForcedTransparents++;
1196       return;                                    817       return;
1197     }                                            818     }
1198                                                  819 
1199     // Check if we have an absorption:           820     // Check if we have an absorption:
1200     if(theEventInfo.nucleonAbsorption) theGlo    821     if(theEventInfo.nucleonAbsorption) theGlobalInfo.nNucleonAbsorptions++;
1201     if(theEventInfo.pionAbsorption) theGlobal    822     if(theEventInfo.pionAbsorption) theGlobalInfo.nPionAbsorptions++;
1202                                                  823 
1203     // Count complete-fusion events              824     // Count complete-fusion events
1204     if(theEventInfo.nCascadeParticles==0) the    825     if(theEventInfo.nCascadeParticles==0) theGlobalInfo.nCompleteFusion++;
1205                                                  826 
1206     if(nucleus->getTryCompoundNucleus())         827     if(nucleus->getTryCompoundNucleus())
1207       theGlobalInfo.nForcedCompoundNucleus++;    828       theGlobalInfo.nForcedCompoundNucleus++;
1208                                                  829 
1209     // Counters for the number of violations     830     // Counters for the number of violations of energy conservation in
1210     // collisions                                831     // collisions
1211     theGlobalInfo.nEnergyViolationInteraction    832     theGlobalInfo.nEnergyViolationInteraction += theEventInfo.nEnergyViolationInteraction;
1212   }                                           << 
1213                                               << 
1214   G4double INCL::read_file(std::string filena << 
1215                            std::vector<std::v << 
1216     std::ifstream file(filename);             << 
1217     G4double sum_probs = 0.0;                 << 
1218     if (file.is_open()) {                     << 
1219       G4String line;                          << 
1220       while (getline(file, line)) {           << 
1221         std::istringstream iss(line);         << 
1222         G4double prob;                        << 
1223         iss >> prob;                          << 
1224         sum_probs += prob;                    << 
1225         probabilities.push_back(prob);        << 
1226         std::vector<G4String> types;          << 
1227         G4String type;                        << 
1228         while (iss >> type) {                 << 
1229           types.push_back(type);              << 
1230         }                                     << 
1231         particle_types.push_back(std::move(ty << 
1232       }                                       << 
1233     } else {                                  << 
1234 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1235       G4cout << "ERROR no fread_file " << fil << 
1236 #else                                         << 
1237       std::cout << "ERROR no fread_file " <<  << 
1238 #endif                                        << 
1239     }                                         << 
1240     return sum_probs;                         << 
1241   }                                           << 
1242                                               << 
1243                                               << 
1244   G4int INCL::findStringNumber(G4double rdm,  << 
1245     G4int stringNumber = -1;                  << 
1246     G4double smallestsum = 0.0;               << 
1247     G4double biggestsum = yields[0];          << 
1248     //G4cout << "initial input " << rdm << G4 << 
1249     for (G4int i = 0; i < static_cast<G4int>( << 
1250       if (rdm >= smallestsum && rdm <= bigges << 
1251         //G4cout << smallestsum << " and " << << 
1252         stringNumber = i+1;                   << 
1253       }                                       << 
1254       smallestsum += yields[i];               << 
1255       biggestsum += yields[i+1];              << 
1256     }                                         << 
1257     if(stringNumber==-1) stringNumber = stati << 
1258     if(stringNumber==-1){                     << 
1259       INCL_ERROR("ERROR in findStringNumber ( << 
1260 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1261       G4cout << "ERROR in findStringNumber" < << 
1262 #else                                         << 
1263       std::cout << "ERROR in findStringNumber << 
1264 #endif                                        << 
1265     }                                         << 
1266     return stringNumber;                      << 
1267   }                                           << 
1268                                               << 
1269                                               << 
1270   void INCL::preCascade_pbarH1(ParticleSpecie << 
1271     // Reset theEventInfo                     << 
1272     theEventInfo.reset();                     << 
1273                                               << 
1274     EventInfo::eventNumber++;                 << 
1275                                               << 
1276     // Fill in the event information          << 
1277     theEventInfo.projectileType = projectileS << 
1278     theEventInfo.Ap = -1;                     << 
1279     theEventInfo.Zp = -1;                     << 
1280     theEventInfo.Sp = 0;                      << 
1281     theEventInfo.Ep = kineticEnergy;          << 
1282     theEventInfo.St = 0;                      << 
1283     theEventInfo.At = 1;                      << 
1284     theEventInfo.Zt = 1;                      << 
1285   }                                           << 
1286                                               << 
1287                                               << 
1288   void INCL::postCascade_pbarH1(ParticleList  << 
1289     theEventInfo.nParticles = 0;              << 
1290                                               << 
1291     // Reset the remnant counter              << 
1292     theEventInfo.nRemnants = 0;               << 
1293     theEventInfo.history.clear();             << 
1294                                               << 
1295     for(ParticleIter i=outgoingParticles.begi << 
1296       theEventInfo.A[theEventInfo.nParticles] << 
1297       theEventInfo.Z[theEventInfo.nParticles] << 
1298       theEventInfo.S[theEventInfo.nParticles] << 
1299       theEventInfo.EKin[theEventInfo.nParticl << 
1300       ThreeVector mom = (*i)->getMomentum();  << 
1301       theEventInfo.px[theEventInfo.nParticles << 
1302       theEventInfo.py[theEventInfo.nParticles << 
1303       theEventInfo.pz[theEventInfo.nParticles << 
1304       theEventInfo.theta[theEventInfo.nPartic << 
1305       theEventInfo.phi[theEventInfo.nParticle << 
1306       theEventInfo.origin[theEventInfo.nParti << 
1307 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1308       theEventInfo.parentResonancePDGCode[the << 
1309       theEventInfo.parentResonanceID[theEvent << 
1310 #endif                                        << 
1311       theEventInfo.history.push_back("");     << 
1312       ParticleSpecies pt((*i)->getType());    << 
1313       theEventInfo.PDGCode[theEventInfo.nPart << 
1314       theEventInfo.nParticles++;              << 
1315     }                                         << 
1316     theEventInfo.nCascadeParticles = theEvent << 
1317   }                                           << 
1318                                               << 
1319                                               << 
1320   void INCL::preCascade_pbarH2(ParticleSpecie << 
1321     // Reset theEventInfo                     << 
1322     theEventInfo.reset();                     << 
1323                                               << 
1324     EventInfo::eventNumber++;                 << 
1325                                               << 
1326     // Fill in the event information          << 
1327     theEventInfo.projectileType = projectileS << 
1328     theEventInfo.Ap = -1;                     << 
1329     theEventInfo.Zp = -1;                     << 
1330     theEventInfo.Sp = 0;                      << 
1331     theEventInfo.Ep = kineticEnergy;          << 
1332     theEventInfo.St = 0;                      << 
1333     theEventInfo.At = 2;                      << 
1334     theEventInfo.Zt = 1;                      << 
1335   }                                           << 
1336                                               << 
1337                                               << 
1338   void INCL::postCascade_pbarH2(ParticleList  << 
1339     theEventInfo.nParticles = 0;              << 
1340                                               << 
1341     // Reset the remnant counter              << 
1342     theEventInfo.nRemnants = 0;               << 
1343     theEventInfo.history.clear();             << 
1344                                               << 
1345     for(ParticleIter i=outgoingParticles.begi << 
1346       theEventInfo.A[theEventInfo.nParticles] << 
1347       theEventInfo.Z[theEventInfo.nParticles] << 
1348       theEventInfo.S[theEventInfo.nParticles] << 
1349       theEventInfo.EKin[theEventInfo.nParticl << 
1350       ThreeVector mom = (*i)->getMomentum();  << 
1351       theEventInfo.px[theEventInfo.nParticles << 
1352       theEventInfo.py[theEventInfo.nParticles << 
1353       theEventInfo.pz[theEventInfo.nParticles << 
1354       theEventInfo.theta[theEventInfo.nPartic << 
1355       theEventInfo.phi[theEventInfo.nParticle << 
1356       theEventInfo.origin[theEventInfo.nParti << 
1357 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1358       theEventInfo.parentResonancePDGCode[the << 
1359       theEventInfo.parentResonanceID[theEvent << 
1360 #endif                                        << 
1361       theEventInfo.history.push_back("");     << 
1362       ParticleSpecies pt((*i)->getType());    << 
1363       theEventInfo.PDGCode[theEventInfo.nPart << 
1364       theEventInfo.nParticles++;              << 
1365     }                                         << 
1366                                               << 
1367     for(ParticleIter i=H2Particles.begin(), e << 
1368       theEventInfo.A[theEventInfo.nParticles] << 
1369       theEventInfo.Z[theEventInfo.nParticles] << 
1370       theEventInfo.S[theEventInfo.nParticles] << 
1371       theEventInfo.EKin[theEventInfo.nParticl << 
1372       ThreeVector mom = (*i)->getMomentum();  << 
1373       theEventInfo.px[theEventInfo.nParticles << 
1374       theEventInfo.py[theEventInfo.nParticles << 
1375       theEventInfo.pz[theEventInfo.nParticles << 
1376       theEventInfo.theta[theEventInfo.nPartic << 
1377       theEventInfo.phi[theEventInfo.nParticle << 
1378       theEventInfo.origin[theEventInfo.nParti << 
1379 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1380       theEventInfo.parentResonancePDGCode[the << 
1381       theEventInfo.parentResonanceID[theEvent << 
1382 #endif                                        << 
1383       theEventInfo.history.push_back("");     << 
1384       ParticleSpecies pt((*i)->getType());    << 
1385       theEventInfo.PDGCode[theEventInfo.nPart << 
1386       theEventInfo.nParticles++;              << 
1387     }                                         << 
1388     theEventInfo.nCascadeParticles = theEvent << 
1389   }                                              833   }
1390                                                  834 
1391 }                                                835 }
1392                                                  836