Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/incl_physics/src/G4INCLNucleus.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/G4INCLNucleus.cc (Version 11.3.0) and /processes/hadronic/models/inclxx/incl_physics/src/G4INCLNucleus.cc (Version 9.6.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 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
 28 // Joseph Cugnon, University of Liege, Belgium <<  28 // Davide Mancusi, CEA
 29 // Jean-Christophe David, CEA-Saclay, France   <<  29 // Alain Boudard, CEA
 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H <<  30 // Sylvie Leray, CEA
 31 // Sylvie Leray, CEA-Saclay, France            <<  31 // Joseph Cugnon, University of Liege
 32 // Davide Mancusi, CEA-Saclay, France          << 
 33 //                                                 32 //
 34 #define INCLXX_IN_GEANT4_MODE 1                    33 #define INCLXX_IN_GEANT4_MODE 1
 35                                                    34 
 36 #include "globals.hh"                              35 #include "globals.hh"
 37                                                    36 
 38 /*                                                 37 /*
 39  * G4INCLNucleus.cc                                38  * G4INCLNucleus.cc
 40  *                                                 39  *
 41  *  \date Jun 5, 2009                              40  *  \date Jun 5, 2009
 42  * \author Pekka Kaitaniemi                        41  * \author Pekka Kaitaniemi
 43  */                                                42  */
 44                                                    43 
 45 #ifndef G4INCLNucleus_hh                           44 #ifndef G4INCLNucleus_hh
 46 #define G4INCLNucleus_hh 1                         45 #define G4INCLNucleus_hh 1
 47                                                    46 
 48 #include "G4INCLGlobals.hh"                        47 #include "G4INCLGlobals.hh"
 49 #include "G4INCLLogger.hh"                         48 #include "G4INCLLogger.hh"
 50 #include "G4INCLParticle.hh"                       49 #include "G4INCLParticle.hh"
 51 #include "G4INCLIAvatar.hh"                        50 #include "G4INCLIAvatar.hh"
 52 #include "G4INCLNucleus.hh"                        51 #include "G4INCLNucleus.hh"
 53 #include "G4INCLKinematicsUtils.hh"                52 #include "G4INCLKinematicsUtils.hh"
 54 #include "G4INCLDecayAvatar.hh"                    53 #include "G4INCLDecayAvatar.hh"
 55 #include "G4INCLStrangeAbsorbtionChannel.hh"   << 
 56 #include "G4INCLCluster.hh"                        54 #include "G4INCLCluster.hh"
 57 #include "G4INCLClusterDecay.hh"                   55 #include "G4INCLClusterDecay.hh"
 58 #include "G4INCLDeJongSpin.hh"                     56 #include "G4INCLDeJongSpin.hh"
 59 #include "G4INCLParticleSpecies.hh"            <<  57 #include "G4INCLNuclearPotentialEnergyIsospinSmooth.hh"
 60 #include "G4INCLParticleTable.hh"              <<  58 #include "G4INCLNuclearPotentialEnergyIsospin.hh"
                                                   >>  59 #include "G4INCLNuclearPotentialIsospin.hh"
                                                   >>  60 #include "G4INCLNuclearPotentialConstant.hh"
 61 #include <iterator>                                61 #include <iterator>
 62 #include <cstdlib>                                 62 #include <cstdlib>
 63 #include <sstream>                                 63 #include <sstream>
 64 // #include <cassert>                              64 // #include <cassert>
 65 #include "G4INCLPbarAtrestEntryChannel.hh"     << 
 66 #include "G4INCLBinaryCollisionAvatar.hh"      << 
 67                                                    65 
 68 namespace G4INCL {                                 66 namespace G4INCL {
 69                                                <<  67 
 70   Nucleus::Nucleus(G4int mass, G4int charge, G <<  68   Nucleus::Nucleus(G4int mass, G4int charge, Config const * const conf, const G4double universeRadius)
 71     AnnihilationType AType) //D                <<  69     : Cluster(charge,mass),
 72     : Cluster(charge,mass,strangess,true),     <<  70      theInitialZ(charge), theInitialA(mass),
 73      theInitialZ(charge), theInitialA(mass), t <<  71      theNpInitial(0), theNnInitial(0),
 74      theNpInitial(0), theNnInitial(0),         << 
 75      theNpionplusInitial(0), theNpionminusInit << 
 76      theNkaonplusInitial(0), theNkaonminusInit << 
 77      theNantiprotonInitial(0),                 << 
 78      initialInternalEnergy(0.),                    72      initialInternalEnergy(0.),
 79      incomingAngularMomentum(0.,0.,0.), incomi     73      incomingAngularMomentum(0.,0.,0.), incomingMomentum(0.,0.,0.),
 80      initialCenterOfMass(0.,0.,0.),                74      initialCenterOfMass(0.,0.,0.),
 81      remnant(true),                                75      remnant(true),
                                                   >>  76      blockedDelta(NULL),
 82      initialEnergy(0.),                            77      initialEnergy(0.),
 83      tryCN(false),                                 78      tryCN(false),
                                                   >>  79      forceTransparent(false),
                                                   >>  80      projectileZ(0),
                                                   >>  81      projectileA(0),
 84      theUniverseRadius(universeRadius),            82      theUniverseRadius(universeRadius),
 85      isNucleusNucleus(false),                      83      isNucleusNucleus(false),
 86      theProjectileRemnant(NULL),                   84      theProjectileRemnant(NULL),
 87      theDensity(NULL),                             85      theDensity(NULL),
 88      thePotential(NULL),                       <<  86      thePotential(NULL)
 89      theAType(AType)                           << 
 90   {                                                87   {
 91     PotentialType potentialType;                   88     PotentialType potentialType;
 92     G4bool pionPotential;                          89     G4bool pionPotential;
 93     if(conf) {                                     90     if(conf) {
 94       potentialType = conf->getPotentialType()     91       potentialType = conf->getPotentialType();
 95       pionPotential = conf->getPionPotential()     92       pionPotential = conf->getPionPotential();
 96     } else { // By default we don't use energy     93     } else { // By default we don't use energy dependent
 97       // potential. This is convenient for som     94       // potential. This is convenient for some tests.
 98       potentialType = IsospinPotential;            95       potentialType = IsospinPotential;
 99       pionPotential = true;                        96       pionPotential = true;
100     }                                              97     }
101                                                <<  98     switch(potentialType) {
102     thePotential = NuclearPotential::createPot <<  99       case IsospinEnergySmoothPotential:
                                                   >> 100         thePotential = new NuclearPotential::NuclearPotentialEnergyIsospinSmooth(theA, theZ, pionPotential);
                                                   >> 101         break;
                                                   >> 102       case IsospinEnergyPotential:
                                                   >> 103         thePotential = new NuclearPotential::NuclearPotentialEnergyIsospin(theA, theZ, pionPotential);
                                                   >> 104         break;
                                                   >> 105       case IsospinPotential:
                                                   >> 106         thePotential = new NuclearPotential::NuclearPotentialIsospin(theA, theZ, pionPotential);
                                                   >> 107         break;
                                                   >> 108       case ConstantPotential:
                                                   >> 109         thePotential = new NuclearPotential::NuclearPotentialConstant(theA, theZ, pionPotential);
                                                   >> 110         break;
                                                   >> 111       default:
                                                   >> 112         FATAL("Unrecognized potential type at Nucleus creation." << std::endl);
                                                   >> 113         break;
                                                   >> 114     }
103                                                   115 
104     ParticleTable::setProtonSeparationEnergy(t    116     ParticleTable::setProtonSeparationEnergy(thePotential->getSeparationEnergy(Proton));
105     ParticleTable::setNeutronSeparationEnergy(    117     ParticleTable::setNeutronSeparationEnergy(thePotential->getSeparationEnergy(Neutron));
106                                                   118 
107     if (theAType==PType) theDensity = NuclearD << 119     theDensity = NuclearDensityFactory::createDensity(theA, theZ);
108     else if (theAType==NType) theDensity = Nuc << 
109     else                                       << 
110     theDensity = NuclearDensityFactory::create << 
111                                                   120 
112     theParticleSampler->setPotential(thePotent    121     theParticleSampler->setPotential(thePotential);
113     theParticleSampler->setDensity(theDensity)    122     theParticleSampler->setDensity(theDensity);
114                                                   123 
115     if(theUniverseRadius<0)                       124     if(theUniverseRadius<0)
116       theUniverseRadius = theDensity->getMaxim    125       theUniverseRadius = theDensity->getMaximumRadius();
117     theStore = new Store(conf);                   126     theStore = new Store(conf);
                                                   >> 127     toBeUpdated.clear();
118   }                                               128   }
119                                                   129 
120   Nucleus::~Nucleus() {                           130   Nucleus::~Nucleus() {
121     delete theStore;                              131     delete theStore;
122     deleteProjectileRemnant();                 << 
123     /* We don't delete the potential and the d << 
124      * are caching them                        << 
125     delete thePotential;                          132     delete thePotential;
                                                   >> 133     /* We don't delete the density here any more -- the Factory is caching them
126     delete theDensity;*/                          134     delete theDensity;*/
127   }                                               135   }
128                                                   136 
129   AnnihilationType Nucleus::getAType() const { << 
130     return theAType;                           << 
131   }                                            << 
132                                                << 
133   void Nucleus::setAType(AnnihilationType type << 
134     theAType = type;                           << 
135   }                                            << 
136                                                << 
137   void Nucleus::initializeParticles() {           137   void Nucleus::initializeParticles() {
138     // Reset the variables connected with the     138     // Reset the variables connected with the projectile remnant
139     delete theProjectileRemnant;                  139     delete theProjectileRemnant;
140     theProjectileRemnant = NULL;                  140     theProjectileRemnant = NULL;
141     Cluster::initializeParticles();            << 
142                                                   141 
143     for(ParticleIter i=particles.begin(), e=pa << 142     Cluster::initializeParticles();
                                                   >> 143     for(ParticleIter i = particles.begin(); i != particles.end(); ++i) {
144       updatePotentialEnergy(*i);                  144       updatePotentialEnergy(*i);
                                                   >> 145       theStore->add(*i);
145     }                                             146     }
146     theStore->add(particles);                  << 
147     particles.clear();                            147     particles.clear();
148     initialInternalEnergy = computeTotalEnergy    148     initialInternalEnergy = computeTotalEnergy();
149     initialCenterOfMass = thePosition;            149     initialCenterOfMass = thePosition;
150   }                                               150   }
151                                                   151 
152   void Nucleus::applyFinalState(FinalState *fi << 152   std::string Nucleus::dump() {
153     if(!finalstate) // do nothing if no final  << 153     std::stringstream ss;
154       return;                                  << 154     ss <<"(list ;; List of participants " << std::endl;
                                                   >> 155     ParticleList participants = theStore->getParticipants();
                                                   >> 156     for(ParticleIter i = participants.begin(); i != participants.end(); ++i) {
                                                   >> 157       ss <<"(make-particle-avatar-map " << std::endl
                                                   >> 158         << (*i)->dump() 
                                                   >> 159         << "(list ;; List of avatars in this particle" << std::endl
                                                   >> 160         << ")) ;; Close the list of avatars and the particle-avatar-map" << std::endl;
                                                   >> 161     }
                                                   >> 162     ss << ")" << std::endl;
                                                   >> 163     return ss.str();
                                                   >> 164   }
155                                                   165 
                                                   >> 166   void Nucleus::applyFinalState(FinalState *finalstate) {
                                                   >> 167     justCreated.clear();
                                                   >> 168     toBeUpdated.clear(); // Clear the list of particles to be updated by the propagation model.
                                                   >> 169     blockedDelta = NULL;
156     G4double totalEnergy = 0.0;                   170     G4double totalEnergy = 0.0;
157                                                   171 
158     FinalStateValidity const validity = finals    172     FinalStateValidity const validity = finalstate->getValidity();
159     if(validity == ValidFS) {                     173     if(validity == ValidFS) {
160                                                   174 
161       ParticleList const &created = finalstate    175       ParticleList const &created = finalstate->getCreatedParticles();
162       for(ParticleIter iter=created.begin(), e << 176       for(ParticleIter iter = created.begin(); iter != created.end(); ++iter) {
163         theStore->add((*iter));                   177         theStore->add((*iter));
164         if(!(*iter)->isOutOfWell()) {             178         if(!(*iter)->isOutOfWell()) {
165           totalEnergy += (*iter)->getEnergy()     179           totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
                                                   >> 180           justCreated.push_back((*iter));   // New particle, so we must create avatars for it
166         }                                         181         }
167       }                                           182       }
168                                                   183 
169       ParticleList const &deleted = finalstate    184       ParticleList const &deleted = finalstate->getDestroyedParticles();
170       for(ParticleIter iter=deleted.begin(), e << 185       for(ParticleIter iter = deleted.begin(); iter != deleted.end(); ++iter) {
171         theStore->particleHasBeenDestroyed(*it << 186         theStore->particleHasBeenDestroyed((*iter)->getID());
172       }                                           187       }
173                                                   188 
174       ParticleList const &modified = finalstat    189       ParticleList const &modified = finalstate->getModifiedParticles();
175       for(ParticleIter iter=modified.begin(),  << 190       for(ParticleIter iter = modified.begin(); iter != modified.end(); ++iter) {
176         theStore->particleHasBeenUpdated(*iter << 191         theStore->particleHasBeenUpdated((*iter)->getID());
177         totalEnergy += (*iter)->getEnergy() -     192         totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
                                                   >> 193         toBeUpdated.push_back((*iter)); // Particle is modified so we have to create new avatars for it.
178       }                                           194       }
179                                                   195 
180       ParticleList const &out = finalstate->ge    196       ParticleList const &out = finalstate->getOutgoingParticles();
181       for(ParticleIter iter=out.begin(), e=out << 197       for(ParticleIter iter = out.begin(); iter != out.end(); ++iter) {
182         if((*iter)->isCluster()) {                198         if((*iter)->isCluster()) {
183       Cluster *clusterOut = dynamic_cast<Clust << 199     Cluster *clusterOut = dynamic_cast<Cluster*>((*iter));
184 // assert(clusterOut);                         << 200           ParticleList const components = clusterOut->getParticles();
185 #ifdef INCLXX_IN_GEANT4_MODE                   << 201           for(ParticleIter in = components.begin(); in != components.end(); ++in)
186           if(!clusterOut)                      << 202             theStore->particleHasBeenEjected((*in)->getID());
187             continue;                          << 
188 #endif                                         << 
189           ParticleList const &components = clu << 
190           for(ParticleIter in=components.begin << 
191             theStore->particleHasBeenEjected(* << 
192         } else {                                  203         } else {
193           theStore->particleHasBeenEjected(*it << 204           theStore->particleHasBeenEjected((*iter)->getID());
194         }                                         205         }
195         totalEnergy += (*iter)->getEnergy();      206         totalEnergy += (*iter)->getEnergy();      // No potential here because the particle is gone
196         theA -= (*iter)->getA();                  207         theA -= (*iter)->getA();
197         theZ -= (*iter)->getZ();                  208         theZ -= (*iter)->getZ();
198         theS -= (*iter)->getS();               << 
199         theStore->addToOutgoing(*iter);           209         theStore->addToOutgoing(*iter);
200         (*iter)->setEmissionTime(theStore->get << 210         (*iter)->setEmissionTime(theStore->getBook()->getCurrentTime());
201       }                                           211       }
202                                                   212 
203       ParticleList const &entering = finalstat    213       ParticleList const &entering = finalstate->getEnteringParticles();
204       for(ParticleIter iter=entering.begin(),  << 214       for(ParticleIter iter = entering.begin(); iter != entering.end(); ++iter) {
205         insertParticle(*iter);                    215         insertParticle(*iter);
206         totalEnergy += (*iter)->getEnergy() -     216         totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
                                                   >> 217         toBeUpdated.push_back((*iter)); // Particle is modified so we have to create new avatars for it.
207       }                                           218       }
208                                                << 219     } else if(validity == PauliBlockedFS) {
209       // actually perform the removal of the s << 220       blockedDelta = finalstate->getBlockedDelta();
210       theStore->removeScheduledAvatars();      << 221     } else if(validity == ParticleBelowFermiFS) {
211     } else if(validity == ParticleBelowFermiFS << 222       DEBUG("A Particle is entering below the Fermi sea:" << std::endl << finalstate->print() << std::endl);
212       INCL_DEBUG("A Particle is entering below << 
213       tryCN = true;                               223       tryCN = true;
214       ParticleList const &entering = finalstat    224       ParticleList const &entering = finalstate->getEnteringParticles();
215       for(ParticleIter iter=entering.begin(),  << 225       for(ParticleIter iter = entering.begin(); iter != entering.end(); ++iter) {
                                                   >> 226         insertParticle(*iter);
                                                   >> 227       }
                                                   >> 228     } else if(validity == ParticleBelowZeroFS) {
                                                   >> 229       DEBUG("A Particle is entering below zero energy:" << std::endl << finalstate->print() << std::endl);
                                                   >> 230       forceTransparent = true;
                                                   >> 231       ParticleList const &entering = finalstate->getEnteringParticles();
                                                   >> 232       for(ParticleIter iter = entering.begin(); iter != entering.end(); ++iter) {
216         insertParticle(*iter);                    233         insertParticle(*iter);
217       }                                           234       }
218     }                                             235     }
219                                                   236 
220     if(validity==ValidFS &&                       237     if(validity==ValidFS &&
221         std::abs(totalEnergy - finalstate->get    238         std::abs(totalEnergy - finalstate->getTotalEnergyBeforeInteraction()) > 0.1) {
222       INCL_ERROR("Energy nonconservation! Ener << 239       ERROR("Energy nonconservation! Energy at the beginning of the event = "
223           << finalstate->getTotalEnergyBeforeI    240           << finalstate->getTotalEnergyBeforeInteraction()
224           <<" and after interaction = "           241           <<" and after interaction = "
225           << totalEnergy << '\n'               << 242           << totalEnergy << std::endl
226           << finalstate->print());                243           << finalstate->print());
227     }                                             244     }
228   }                                               245   }
229                                                   246 
230   void Nucleus::propagateParticles(G4double /*    247   void Nucleus::propagateParticles(G4double /*step*/) {
231     INCL_WARN("Useless Nucleus::propagateParti << 248     WARN("Useless Nucleus::propagateParticles -method called." << std::endl);
232   }                                               249   }
233                                                   250 
234   G4double Nucleus::computeTotalEnergy() const    251   G4double Nucleus::computeTotalEnergy() const {
235     G4double totalEnergy = 0.0;                   252     G4double totalEnergy = 0.0;
236     ParticleList const &inside = theStore->get << 253     ParticleList inside = theStore->getParticles();
237     for(ParticleIter p=inside.begin(), e=insid << 254     for(ParticleIter p=inside.begin(); p!=inside.end(); ++p) {
238       if((*p)->isNucleon()) // Ugly: we should    255       if((*p)->isNucleon()) // Ugly: we should calculate everything using total energies!
239         totalEnergy += (*p)->getKineticEnergy(    256         totalEnergy += (*p)->getKineticEnergy() - (*p)->getPotentialEnergy();
240       else if((*p)->isResonance())                257       else if((*p)->isResonance())
241         totalEnergy += (*p)->getEnergy() - (*p    258         totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy() - ParticleTable::effectiveNucleonMass;
242       else if((*p)->isHyperon())               << 
243         totalEnergy += (*p)->getEnergy() - (*p << 
244       else if((*p)->isAntiNucleon())           << 
245         totalEnergy += (*p)->getEnergy() - (*p << 
246       else if((*p)->isAntiLambda())            << 
247         totalEnergy += (*p)->getEnergy() - (*p << 
248         //std::cout << ParticleTable::getRealM << 
249       else                                        259       else
250         totalEnergy += (*p)->getEnergy() - (*p    260         totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy();
251     }                                             261     }
252                                                << 
253     return totalEnergy;                           262     return totalEnergy;
254   }                                               263   }
255                                                   264 
256   void Nucleus::computeRecoilKinematics() {       265   void Nucleus::computeRecoilKinematics() {
257     // If the remnant consists of only one nuc    266     // If the remnant consists of only one nucleon, we need to apply a special
258     // procedure to put it on mass shell.         267     // procedure to put it on mass shell.
259     if(theA==1) {                                 268     if(theA==1) {
260       emitInsidePions();                          269       emitInsidePions();
261       computeOneNucleonRecoilKinematics();        270       computeOneNucleonRecoilKinematics();
262       remnant=false;                              271       remnant=false;
263       return;                                     272       return;
264     }                                             273     }
265                                                   274 
266     // Compute the recoil momentum and angular    275     // Compute the recoil momentum and angular momentum
267     theMomentum = incomingMomentum;               276     theMomentum = incomingMomentum;
268     theSpin = incomingAngularMomentum;            277     theSpin = incomingAngularMomentum;
269                                                   278 
270     ParticleList const &outgoing = theStore->g << 279     ParticleList outgoing = theStore->getOutgoingParticles();
271     for(ParticleIter p=outgoing.begin(), e=out << 280     for(ParticleIter p=outgoing.begin(); p!=outgoing.end(); ++p)
                                                   >> 281     {
272       theMomentum -= (*p)->getMomentum();         282       theMomentum -= (*p)->getMomentum();
273       theSpin -= (*p)->getAngularMomentum();      283       theSpin -= (*p)->getAngularMomentum();
274     }                                             284     }
275     if(theProjectileRemnant) {                 << 
276       theMomentum -= theProjectileRemnant->get << 
277       theSpin -= theProjectileRemnant->getAngu << 
278     }                                          << 
279                                                   285 
280     // Subtract orbital angular momentum          286     // Subtract orbital angular momentum
281     thePosition = computeCenterOfMass();          287     thePosition = computeCenterOfMass();
282     theSpin -= (thePosition-initialCenterOfMas    288     theSpin -= (thePosition-initialCenterOfMass).vector(theMomentum);
283                                                   289 
284     setMass(ParticleTable::getTableMass(theA,t << 290     setMass(ParticleTable::getTableMass(theA,theZ) + theExcitationEnergy);
285     adjustEnergyFromMomentum();                   291     adjustEnergyFromMomentum();
286     remnant=true;                                 292     remnant=true;
287   }                                               293   }
288                                                   294 
289   ThreeVector Nucleus::computeCenterOfMass() c    295   ThreeVector Nucleus::computeCenterOfMass() const {
290     ThreeVector cm(0.,0.,0.);                     296     ThreeVector cm(0.,0.,0.);
291     G4double totalMass = 0.0;                     297     G4double totalMass = 0.0;
292     ParticleList const &inside = theStore->get << 298     ParticleList inside = theStore->getParticles();
293     for(ParticleIter p=inside.begin(), e=insid << 299     for(ParticleIter p=inside.begin(); p!=inside.end(); ++p) {
294       const G4double mass = (*p)->getMass();      300       const G4double mass = (*p)->getMass();
295       cm += (*p)->getPosition() * mass;           301       cm += (*p)->getPosition() * mass;
296       totalMass += mass;                          302       totalMass += mass;
297     }                                             303     }
298     cm /= totalMass;                              304     cm /= totalMass;
299     return cm;                                    305     return cm;
300   }                                               306   }
301                                                   307 
302   G4double Nucleus::computeExcitationEnergy()     308   G4double Nucleus::computeExcitationEnergy() const {
303     const G4double totalEnergy = computeTotalE    309     const G4double totalEnergy = computeTotalEnergy();
304     const G4double separationEnergies = comput    310     const G4double separationEnergies = computeSeparationEnergyBalance();
305                                                   311 
306 G4double eSep = 0;                             << 312     return totalEnergy - initialInternalEnergy - separationEnergies;
307 if (getAType() == AnnihilationType::Def) {     << 
308 } else if (getAType()  == AnnihilationType::PT << 
309 } else if (getAType()  == AnnihilationType::NT << 
310 } else if (getAType()  == AnnihilationType::PT << 
311   eSep = ParticleTable::getProtonSeparationEne << 
312 } else if (getAType()  == AnnihilationType::NT << 
313   eSep = ParticleTable::getNeutronSeparationEn << 
314 } else if (getAType()  == AnnihilationType::Nb << 
315   eSep = ParticleTable::getProtonSeparationEne << 
316 } else if (getAType()  == AnnihilationType::Nb << 
317   eSep = ParticleTable::getNeutronSeparationEn << 
318 }                                              << 
319                                                << 
320   if (eSep > 0. && (totalEnergy - initialInter << 
321      INCL_DEBUG("Negative Excitation Energy du << 
322   }                                            << 
323                                                << 
324   return totalEnergy - initialInternalEnergy - << 
325                                                << 
326   }                                               313   }
327                                                   314 
328 //thePotential->getSeparationEnergy(Proton)    << 
329                                                << 
330   std::string Nucleus::print()                    315   std::string Nucleus::print()
331   {                                               316   {
332     std::stringstream ss;                         317     std::stringstream ss;
333     ss << "Particles in the nucleus:" << '\n'  << 318     ss << "Particles in the nucleus:" << std::endl
334       << "Inside:" << '\n';                    << 319       << "Participants:" << std::endl;
335     G4int counter = 1;                            320     G4int counter = 1;
336     ParticleList const &inside = theStore->get << 321     ParticleList participants = theStore->getParticipants();
337     for(ParticleIter p=inside.begin(), e=insid << 322     for(ParticleIter p = participants.begin(); p != participants.end(); ++p) {
338       ss << "index = " << counter << '\n'      << 323       ss << "index = " << counter << std::endl
339         << (*p)->print();                         324         << (*p)->print();
340       counter++;                                  325       counter++;
341     }                                             326     }
342     ss <<"Outgoing:" << '\n';                  << 327     ss <<"Spectators:" << std::endl;
343     ParticleList const &outgoing = theStore->g << 328     ParticleList spectators = theStore->getSpectators();
344     for(ParticleIter p=outgoing.begin(), e=out << 329     for(ParticleIter p = spectators.begin(); p != spectators.end(); ++p)
                                                   >> 330       ss << (*p)->print();
                                                   >> 331     ss <<"Outgoing:" << std::endl;
                                                   >> 332     ParticleList outgoing = theStore->getOutgoingParticles();
                                                   >> 333     for(ParticleIter p = outgoing.begin(); p != outgoing.end(); ++p)
345       ss << (*p)->print();                        334       ss << (*p)->print();
346                                                   335 
347     return ss.str();                              336     return ss.str();
348   }                                               337   }
349                                                   338 
350   G4bool Nucleus::decayOutgoingDeltas() {         339   G4bool Nucleus::decayOutgoingDeltas() {
351     ParticleList const &out = theStore->getOut << 340     ParticleList out = theStore->getOutgoingParticles();
352     ParticleList deltas;                          341     ParticleList deltas;
353     for(ParticleIter i=out.begin(), e=out.end( << 342     for(ParticleIter i = out.begin(); i != out.end(); ++i) {
354       if((*i)->isDelta()) deltas.push_back((*i    343       if((*i)->isDelta()) deltas.push_back((*i));
355     }                                             344     }
356     if(deltas.empty()) return false;              345     if(deltas.empty()) return false;
357                                                   346 
358     for(ParticleIter i=deltas.begin(), e=delta << 347     for(ParticleIter i = deltas.begin(); i != deltas.end(); ++i) {
359       INCL_DEBUG("Decay outgoing delta particl << 348       DEBUG("Decay outgoing delta particle:" << std::endl
360           << (*i)->print() << '\n');           << 349           << (*i)->print() << std::endl);
361       const ThreeVector beta = -(*i)->boostVec    350       const ThreeVector beta = -(*i)->boostVector();
362       const G4double deltaMass = (*i)->getMass    351       const G4double deltaMass = (*i)->getMass();
363                                                   352 
364       // Set the delta momentum to zero and sa    353       // Set the delta momentum to zero and sample the decay in the CM frame.
365       // This makes life simpler if we are usi    354       // This makes life simpler if we are using real particle masses.
366       (*i)->setMomentum(ThreeVector());           355       (*i)->setMomentum(ThreeVector());
367       (*i)->setEnergy((*i)->getMass());           356       (*i)->setEnergy((*i)->getMass());
368                                                   357 
369       // Use a DecayAvatar                        358       // Use a DecayAvatar
370       IAvatar *decay = new DecayAvatar((*i), 0    359       IAvatar *decay = new DecayAvatar((*i), 0.0, NULL);
371       FinalState *fs = decay->getFinalState();    360       FinalState *fs = decay->getFinalState();
372       Particle * const pion = fs->getCreatedPa    361       Particle * const pion = fs->getCreatedParticles().front();
373       Particle * const nucleon = fs->getModifi    362       Particle * const nucleon = fs->getModifiedParticles().front();
374                                                   363 
375       // Adjust the decay momentum if we are u    364       // Adjust the decay momentum if we are using the real masses
376       const G4double decayMomentum = Kinematic    365       const G4double decayMomentum = KinematicsUtils::momentumInCM(deltaMass,
377           nucleon->getTableMass(),                366           nucleon->getTableMass(),
378           pion->getTableMass());                  367           pion->getTableMass());
379       ThreeVector newMomentum = pion->getMomen    368       ThreeVector newMomentum = pion->getMomentum();
380       newMomentum *= decayMomentum / newMoment    369       newMomentum *= decayMomentum / newMomentum.mag();
381                                                   370 
382       pion->setTableMass();                       371       pion->setTableMass();
383       pion->setMomentum(newMomentum);             372       pion->setMomentum(newMomentum);
384       pion->adjustEnergyFromMomentum();           373       pion->adjustEnergyFromMomentum();
385       pion->setEmissionTime(nucleon->getEmissi << 374       pion->setEmissionTime(theStore->getBook()->getCurrentTime());
386       pion->boost(beta);                          375       pion->boost(beta);
387       pion->setBiasCollisionVector(nucleon->ge << 
388                                                   376 
389       nucleon->setTableMass();                    377       nucleon->setTableMass();
390       nucleon->setMomentum(-newMomentum);         378       nucleon->setMomentum(-newMomentum);
391       nucleon->adjustEnergyFromMomentum();        379       nucleon->adjustEnergyFromMomentum();
                                                   >> 380       nucleon->setEmissionTime(theStore->getBook()->getCurrentTime());
392       nucleon->boost(beta);                       381       nucleon->boost(beta);
393                                                   382 
394       theStore->addToOutgoing(pion);              383       theStore->addToOutgoing(pion);
395                                                   384 
396       delete fs;                                  385       delete fs;
397       delete decay;                               386       delete decay;
398     }                                             387     }
399                                                   388 
400     return true;                                  389     return true;
401   }                                               390   }
402                                                   391 
403   G4bool Nucleus::decayInsideDeltas() {           392   G4bool Nucleus::decayInsideDeltas() {
404     /* If there is a pion potential, do nothin    393     /* If there is a pion potential, do nothing (deltas will be counted as
405      * excitation energy).                        394      * excitation energy).
406      * If, however, the remnant is unphysical     395      * If, however, the remnant is unphysical (Z<0 or Z>A), force the deltas to
407      * decay and get rid of all the pions. In     396      * decay and get rid of all the pions. In case you're wondering, you can
408      * end up with Z<0 or Z>A if the remnant c    397      * end up with Z<0 or Z>A if the remnant contains more pi- than protons or
409      * more pi+ than neutrons, respectively.      398      * more pi+ than neutrons, respectively.
410      */                                           399      */
411     const G4bool unphysicalRemnant = (theZ<0 |    400     const G4bool unphysicalRemnant = (theZ<0 || theZ>theA);
412     if(thePotential->hasPionPotential() && !un    401     if(thePotential->hasPionPotential() && !unphysicalRemnant)
413       return false;                               402       return false;
414                                                   403 
415     // Build a list of deltas (avoid modifying    404     // Build a list of deltas (avoid modifying the list you are iterating on).
416     ParticleList const &inside = theStore->get << 405     ParticleList inside = theStore->getParticles();
417     ParticleList deltas;                          406     ParticleList deltas;
418     for(ParticleIter i=inside.begin(), e=insid << 407     for(ParticleIter i = inside.begin(); i != inside.end(); ++i)
419       if((*i)->isDelta()) deltas.push_back((*i    408       if((*i)->isDelta()) deltas.push_back((*i));
420                                                   409 
421     // Loop over the deltas, make them decay      410     // Loop over the deltas, make them decay
422     for(ParticleIter i=deltas.begin(), e=delta << 411     for(ParticleIter i = deltas.begin(); i != deltas.end(); ++i) {
423       INCL_DEBUG("Decay inside delta particle: << 412       DEBUG("Decay inside delta particle:" << std::endl
424           << (*i)->print() << '\n');           << 413           << (*i)->print() << std::endl);
425       // Create a forced-decay avatar. Note th    414       // Create a forced-decay avatar. Note the last boolean parameter. Note
426       // also that if the remnant is unphysica    415       // also that if the remnant is unphysical we more or less explicitly give
427       // up energy conservation and CDPP by pa    416       // up energy conservation and CDPP by passing a NULL pointer for the
428       // nucleus.                                 417       // nucleus.
429       IAvatar *decay;                             418       IAvatar *decay;
430       if(unphysicalRemnant) {                  << 419       if(unphysicalRemnant)
431         INCL_WARN("Forcing delta decay inside  << 
432              << ", Z=" << theZ << "). Might le << 
433              << '\n');                         << 
434         decay = new DecayAvatar((*i), 0.0, NUL    420         decay = new DecayAvatar((*i), 0.0, NULL, true);
435       } else                                   << 421       else
436         decay = new DecayAvatar((*i), 0.0, thi    422         decay = new DecayAvatar((*i), 0.0, this, true);
437       FinalState *fs = decay->getFinalState();    423       FinalState *fs = decay->getFinalState();
438                                                   424 
439       // The pion can be ejected only if we ma    425       // The pion can be ejected only if we managed to satisfy energy
440       // conservation and if pion emission doe    426       // conservation and if pion emission does not lead to negative excitation
441       // energies.                                427       // energies.
442       if(fs->getValidity()==ValidFS) {            428       if(fs->getValidity()==ValidFS) {
443         // Apply the final state to the nucleu    429         // Apply the final state to the nucleus
444         applyFinalState(fs);                      430         applyFinalState(fs);
445       }                                           431       }
446       delete fs;                                  432       delete fs;
447       delete decay;                               433       delete decay;
448     }                                             434     }
449                                                   435 
450     // If the remnant is unphysical, emit all     436     // If the remnant is unphysical, emit all the pions
451     if(unphysicalRemnant) {                       437     if(unphysicalRemnant) {
452       INCL_DEBUG("Remnant is unphysical: Z=" < << 438       DEBUG("Remnant is unphysical: Z=" << theZ << ", A=" << theA << std::endl);
453       emitInsidePions();                          439       emitInsidePions();
454     }                                             440     }
455                                                   441 
456     return true;                                  442     return true;
457   }                                               443   }
458                                                << 
459   G4bool Nucleus::decayInsideStrangeParticles( << 
460                                                << 
461     /* Transform each strange particles into a << 
462      * Every Kaon (KPlus and KZero) are emited << 
463      */                                        << 
464     const G4bool unphysicalRemnant = (theZ<0 | << 
465     if(unphysicalRemnant){                     << 
466         emitInsideStrangeParticles();          << 
467         INCL_WARN("Remnant is unphysical: Z="  << 
468         return false;                          << 
469     }                                          << 
470                                                   444 
471     /* Build a list of particles with a strang << 
472      * and two other one for proton and neutro << 
473      */                                        << 
474     ParticleList const &inside = theStore->get << 
475     ParticleList stranges;                     << 
476     ParticleList protons;                      << 
477     ParticleList neutrons;                     << 
478     for(ParticleIter i=inside.begin(), e=insid << 
479         if((*i)->isSigma() || (*i)->isAntiKaon << 
480         else if((*i)->isNucleon() && (*i)->get << 
481         else if((*i)->isNucleon() && (*i)->get << 
482     }                                          << 
483                                                << 
484     if((stranges.size() > protons.size()) || ( << 
485         INCL_WARN("Remnant is unphysical: Npro << 
486         emitInsideStrangeParticles();          << 
487         return false;                          << 
488     }                                          << 
489                                                << 
490     // Loop over the strange particles, make t << 
491     ParticleIter protonIter = protons.begin(); << 
492     ParticleIter neutronIter = neutrons.begin( << 
493     for(ParticleIter i=stranges.begin(), e=str << 
494       INCL_DEBUG("Absorbe inside strange parti << 
495           << (*i)->print() << '\n');           << 
496       IAvatar *decay;                          << 
497       if((*i)->getType() == SigmaMinus){       << 
498           decay = new DecayAvatar((*protonIter << 
499           ++protonIter;                        << 
500       }                                        << 
501       else if((*i)->getType() == SigmaPlus){   << 
502           decay = new DecayAvatar((*neutronIte << 
503           ++neutronIter;                       << 
504       }                                        << 
505       else if(Random::shoot()*(protons.size()  << 
506           decay = new DecayAvatar((*protonIter << 
507           ++protonIter;                        << 
508       }                                        << 
509       else {                                   << 
510           decay = new DecayAvatar((*neutronIte << 
511           ++neutronIter;                       << 
512       }                                        << 
513       FinalState *fs = decay->getFinalState(); << 
514       applyFinalState(fs);                     << 
515       delete fs;                               << 
516       delete decay;                            << 
517     }                                          << 
518                                                << 
519     return true;                               << 
520   }                                            << 
521                                                << 
522   G4bool Nucleus::decayOutgoingPionResonances( << 
523         ParticleList const &out = theStore->ge << 
524         ParticleList pionResonances;           << 
525         for(ParticleIter i=out.begin(), e=out. << 
526 //            if((*i)->isEta() || (*i)->isOmeg << 
527             if(((*i)->isEta() && timeThreshold << 
528         }                                      << 
529         if(pionResonances.empty()) return fals << 
530                                                << 
531         for(ParticleIter i=pionResonances.begi << 
532             INCL_DEBUG("Decay outgoing pionRes << 
533                        << (*i)->print() << '\n << 
534             const ThreeVector beta = -(*i)->bo << 
535             const G4double pionResonanceMass = << 
536                                                << 
537             // Set the pionResonance momentum  << 
538             // This makes life simpler if we a << 
539             (*i)->setMomentum(ThreeVector());  << 
540             (*i)->setEnergy((*i)->getMass());  << 
541                                                << 
542             // Use a DecayAvatar               << 
543             IAvatar *decay = new DecayAvatar(( << 
544             FinalState *fs = decay->getFinalSt << 
545                                                << 
546             Particle * const theModifiedPartic << 
547             ParticleList const &created = fs-> << 
548             Particle * const theCreatedParticl << 
549                                                << 
550             if (created.size() == 1) {         << 
551                                                << 
552                 // Adjust the decay momentum i << 
553                 const G4double decayMomentum = << 
554                 ThreeVector newMomentum = theC << 
555                 newMomentum *= decayMomentum / << 
556                                                << 
557                 theCreatedParticle1->setTableM << 
558                 theCreatedParticle1->setMoment << 
559                 theCreatedParticle1->adjustEne << 
560                 //theCreatedParticle1->setEmis << 
561                 theCreatedParticle1->boost(bet << 
562                 theCreatedParticle1->setBiasCo << 
563                                                << 
564                 theModifiedParticle->setTableM << 
565                 theModifiedParticle->setMoment << 
566                 theModifiedParticle->adjustEne << 
567                 theModifiedParticle->boost(bet << 
568                                                << 
569                 theStore->addToOutgoing(theCre << 
570             }                                  << 
571             else if (created.size() == 2) {    << 
572                 Particle * const theCreatedPar << 
573                                                << 
574                 theCreatedParticle1->boost(bet << 
575                 theCreatedParticle1->setBiasCo << 
576                 theCreatedParticle2->boost(bet << 
577                 theCreatedParticle2->setBiasCo << 
578                 theModifiedParticle->boost(bet << 
579                                                << 
580                 theStore->addToOutgoing(theCre << 
581                 theStore->addToOutgoing(theCre << 
582             }                                  << 
583             else {                             << 
584                 INCL_ERROR("Wrong number (< 2) << 
585             }                                  << 
586             delete fs;                         << 
587             delete decay;                      << 
588         }                                      << 
589                                                << 
590         return true;                           << 
591     }                                          << 
592                                                << 
593   G4bool Nucleus::decayOutgoingSigmaZero(G4dou << 
594         ParticleList const &out = theStore->ge << 
595         ParticleList neutralsigma;             << 
596         for(ParticleIter i=out.begin(), e=out. << 
597             if((*i)->getType() == SigmaZero && << 
598         }                                      << 
599         if(neutralsigma.empty()) return false; << 
600                                                << 
601         for(ParticleIter i=neutralsigma.begin( << 
602             INCL_DEBUG("Decay outgoing neutral << 
603                        << (*i)->print() << '\n << 
604             const ThreeVector beta = -(*i)->bo << 
605             const G4double neutralsigmaMass =  << 
606                                                << 
607             // Set the neutral sigma momentum  << 
608             // This makes life simpler if we a << 
609             (*i)->setMomentum(ThreeVector());  << 
610             (*i)->setEnergy((*i)->getMass());  << 
611                                                << 
612             // Use a DecayAvatar               << 
613             IAvatar *decay = new DecayAvatar(( << 
614             FinalState *fs = decay->getFinalSt << 
615                                                << 
616             Particle * const theModifiedPartic << 
617             ParticleList const &created = fs-> << 
618             Particle * const theCreatedParticl << 
619                                                << 
620             if (created.size() == 1) {         << 
621                                                << 
622                 // Adjust the decay momentum i << 
623                 const G4double decayMomentum = << 
624                 ThreeVector newMomentum = theC << 
625                 newMomentum *= decayMomentum / << 
626                                                << 
627                 theCreatedParticle->setTableMa << 
628                 theCreatedParticle->setMomentu << 
629                 theCreatedParticle->adjustEner << 
630                 theCreatedParticle->boost(beta << 
631                 theCreatedParticle->setBiasCol << 
632                                                << 
633                 theModifiedParticle->setTableM << 
634                 theModifiedParticle->setMoment << 
635                 theModifiedParticle->adjustEne << 
636                 theModifiedParticle->boost(bet << 
637                                                << 
638                 theStore->addToOutgoing(theCre << 
639             }                                  << 
640             else {                             << 
641                 INCL_ERROR("Wrong number (!= 1 << 
642             }                                  << 
643             delete fs;                         << 
644             delete decay;                      << 
645         }                                      << 
646                                                << 
647         return true;                           << 
648     }                                          << 
649                                                << 
650   G4bool Nucleus::decayOutgoingNeutralKaon() { << 
651         ParticleList const &out = theStore->ge << 
652         ParticleList neutralkaon;              << 
653         for(ParticleIter i=out.begin(), e=out. << 
654             if((*i)->getType() == KZero  || (* << 
655         }                                      << 
656         if(neutralkaon.empty()) return false;  << 
657                                                << 
658         for(ParticleIter i=neutralkaon.begin() << 
659             INCL_DEBUG("Transform outgoing neu << 
660                        << (*i)->print() << '\n << 
661                                                << 
662             // Use a DecayAvatar               << 
663             IAvatar *decay = new DecayAvatar(( << 
664             FinalState *fs = decay->getFinalSt << 
665                                                << 
666             delete fs;                         << 
667             delete decay;                      << 
668         }                                      << 
669                                                << 
670         return true;                           << 
671     }                                          << 
672                                                << 
673   G4bool Nucleus::decayOutgoingClusters() {       445   G4bool Nucleus::decayOutgoingClusters() {
674     ParticleList const &out = theStore->getOut << 446     ParticleList out = theStore->getOutgoingParticles();
675     ParticleList clusters;                        447     ParticleList clusters;
676     for(ParticleIter i=out.begin(), e=out.end( << 448     for(ParticleIter i = out.begin(); i != out.end(); ++i) {
677       if((*i)->isCluster()) clusters.push_back    449       if((*i)->isCluster()) clusters.push_back((*i));
678     }                                             450     }
679     if(clusters.empty()) return false;            451     if(clusters.empty()) return false;
680                                                   452 
681     for(ParticleIter i=clusters.begin(), e=clu << 453     for(ParticleIter i = clusters.begin(); i != clusters.end(); ++i) {
682       Cluster *cluster = dynamic_cast<Cluster*    454       Cluster *cluster = dynamic_cast<Cluster*>(*i); // Can't avoid using a cast here
683 // assert(cluster);                            << 
684 #ifdef INCLXX_IN_GEANT4_MODE                   << 
685       if(!cluster)                             << 
686         continue;                              << 
687 #endif                                         << 
688       cluster->deleteParticles(); // Don't nee    455       cluster->deleteParticles(); // Don't need them
689       ParticleList decayProducts = ClusterDeca    456       ParticleList decayProducts = ClusterDecay::decay(cluster);
690       for(ParticleIter j=decayProducts.begin() << 457       for(ParticleIter j = decayProducts.begin(); j!=decayProducts.end(); ++j)
691         (*j)->setBiasCollisionVector(cluster-> << 
692         theStore->addToOutgoing(*j);              458         theStore->addToOutgoing(*j);
693       }                                        << 
694     }                                             459     }
695     return true;                                  460     return true;
696   }                                               461   }
697                                                   462 
698   G4bool Nucleus::decayMe() {                     463   G4bool Nucleus::decayMe() {
699     // Do the phase-space decay only if Z=0 or << 464     // Do the phase-space decay only if Z=0 or Z=A
700     if(theA<=1 || (theZ!=0 && (theA+theS)!=the << 465     if(theA<=1 || (theZ!=0 && theA!=theZ))
701       return false;                               466       return false;
702                                                   467 
703     ParticleList decayProducts = ClusterDecay:    468     ParticleList decayProducts = ClusterDecay::decay(this);
704     for(ParticleIter j=decayProducts.begin(),  << 469     for(ParticleIter j = decayProducts.begin(); j!=decayProducts.end(); ++j)
705       (*j)->setBiasCollisionVector(this->getBi << 
706       theStore->addToOutgoing(*j);                470       theStore->addToOutgoing(*j);
707     }                                          << 471 
708                                                << 
709     return true;                                  472     return true;
710   }                                               473   }
711                                                   474 
712   void Nucleus::emitInsidePions() {               475   void Nucleus::emitInsidePions() {
713     /* Forcing emissions of all pions in the n    476     /* Forcing emissions of all pions in the nucleus. This probably violates
714      * energy conservation (although the compu    477      * energy conservation (although the computation of the recoil kinematics
715      * might sweep this under the carpet).        478      * might sweep this under the carpet).
716      */                                           479      */
717     INCL_WARN("Forcing emissions of all pions  << 480     WARN("Forcing emissions of all pions in the nucleus." << std::endl);
718                                                   481 
719     // Emit the pions with this kinetic energy    482     // Emit the pions with this kinetic energy
720     const G4double tinyPionEnergy = 0.1; // Me    483     const G4double tinyPionEnergy = 0.1; // MeV
721                                                   484 
722     // Push out the emitted pions                 485     // Push out the emitted pions
723     ParticleList const &inside = theStore->get << 486     ParticleList inside = theStore->getParticles();
724     ParticleList toEject;                      << 487     for(ParticleIter i = inside.begin(); i != inside.end(); ++i) {
725     for(ParticleIter i=inside.begin(), e=insid << 
726       if((*i)->isPion()) {                        488       if((*i)->isPion()) {
727         Particle * const thePion = *i;         << 489         (*i)->setEmissionTime(theStore->getBook()->getCurrentTime());
728         INCL_DEBUG("Forcing emission of the fo << 
729                    << thePion->print() << '\n' << 
730         thePion->setEmissionTime(theStore->get << 
731         // Correction for real masses             490         // Correction for real masses
732         const G4double theQValueCorrection = t << 491         const G4double theQValueCorrection = (*i)->getEmissionQValueCorrection(theA,theZ);
733         const G4double kineticEnergyOutside =  << 492         const G4double kineticEnergyOutside = (*i)->getKineticEnergy() - (*i)->getPotentialEnergy() + theQValueCorrection;
734         thePion->setTableMass();               << 493         (*i)->setTableMass();
735         if(kineticEnergyOutside > 0.0)            494         if(kineticEnergyOutside > 0.0)
736           thePion->setEnergy(thePion->getMass( << 495           (*i)->setEnergy((*i)->getMass()+kineticEnergyOutside);
737         else                                      496         else
738           thePion->setEnergy(thePion->getMass( << 497           (*i)->setEnergy((*i)->getMass()+tinyPionEnergy);
739         thePion->adjustMomentumFromEnergy();   << 498         (*i)->adjustMomentumFromEnergy();
740         thePion->setPotentialEnergy(0.);       << 499         (*i)->setPotentialEnergy(0.);
741         theZ -= thePion->getZ();               << 500         theZ -= (*i)->getZ();
742         toEject.push_back(thePion);            << 501         theStore->particleHasBeenEjected((*i)->getID());
                                                   >> 502         theStore->addToOutgoing(*i);
743       }                                           503       }
744     }                                             504     }
745     for(ParticleIter i=toEject.begin(), e=toEj << 
746       theStore->particleHasBeenEjected(*i);    << 
747       theStore->addToOutgoing(*i);             << 
748       (*i)->setParticleBias(Particle::getTotal << 
749     }                                          << 
750   }                                               505   }
751                                                << 
752   void Nucleus::emitInsideStrangeParticles() { << 
753     /* Forcing emissions of Sigmas and antiKao << 
754      * This probably violates energy conservat << 
755      * (although the computation of the recoil << 
756      * might sweep this under the carpet).     << 
757      */                                        << 
758     INCL_DEBUG("Forcing emissions of all stran << 
759                                                   506 
760     // Emit the strange particles with this ki << 507   G4bool Nucleus::isEventTransparent() const {
761     const G4double tinyEnergy = 0.1; // MeV    << 
762                                                << 
763     // Push out the emitted strange particles  << 
764     ParticleList const &inside = theStore->get << 
765     ParticleList toEject;                      << 
766     for(ParticleIter i=inside.begin(), e=insid << 
767       if((*i)->isSigma() || (*i)->isAntiKaon() << 
768         Particle * const theParticle = *i;     << 
769         INCL_DEBUG("Forcing emission of the fo << 
770                    << theParticle->print() <<  << 
771         theParticle->setEmissionTime(theStore- << 
772         // Correction for real masses          << 
773         const G4double theQValueCorrection = t << 
774         const G4double kineticEnergyOutside =  << 
775         theParticle->setTableMass();           << 
776         if(kineticEnergyOutside > 0.0)         << 
777           theParticle->setEnergy(theParticle-> << 
778         else                                   << 
779           theParticle->setEnergy(theParticle-> << 
780         theParticle->adjustMomentumFromEnergy( << 
781         theParticle->setPotentialEnergy(0.);   << 
782         theA -= theParticle->getA();           << 
783         theZ -= theParticle->getZ();           << 
784         theS -= theParticle->getS();           << 
785         toEject.push_back(theParticle);        << 
786       }                                        << 
787     }                                          << 
788     for(ParticleIter i=toEject.begin(), e=toEj << 
789       theStore->particleHasBeenEjected(*i);    << 
790       theStore->addToOutgoing(*i);             << 
791       (*i)->setParticleBias(Particle::getTotal << 
792     }                                          << 
793   }                                            << 
794                                                   508 
795   G4int Nucleus::emitInsideLambda() {          << 509     // Forced transparent
796     /* Forcing emissions of all Lambda in the  << 510     if(forceTransparent)
797      * This probably violates energy conservat << 511       return true;
798      * (although the computation of the recoil << 
799      * might sweep this under the carpet).     << 
800      */                                        << 
801     INCL_DEBUG("Forcing emissions of all Lambd << 
802                                                   512 
803     // Emit the Lambda with this kinetic energ << 513     ParticleList const &pL = theStore->getOutgoingParticles();
804     const G4double tinyEnergy = 0.1; // MeV    << 514     G4int outZ = 0, outA = 0;
805                                                   515 
806     // Push out the emitted Lambda             << 516     // If any of the particles has undergone a collision, the event is not a
807     ParticleList const &inside = theStore->get << 517     // transparent.
808     ParticleList toEject;                      << 518     for(ParticleIter p = pL.begin(); p != pL.end(); ++p ) {
809     for(ParticleIter i=inside.begin(), e=insid << 519       if( (*p)->getNumberOfCollisions() != 0 ) return false;
810       if((*i)->isLambda()) {                   << 520       if( (*p)->getNumberOfDecays() != 0 ) return false;
811         Particle * const theLambda = *i;       << 521       outZ += (*p)->getZ();
812         INCL_DEBUG("Forcing emission of the fo << 522       outA += (*p)->getA();
813                    << theLambda->print() << '\ << 
814         theLambda->setEmissionTime(theStore->g << 
815         // Correction for real masses          << 
816         const G4double theQValueCorrection = t << 
817         const G4double kineticEnergyOutside =  << 
818         theLambda->setTableMass();             << 
819         if(kineticEnergyOutside > 0.0)         << 
820           theLambda->setEnergy(theLambda->getM << 
821         else                                   << 
822           theLambda->setEnergy(theLambda->getM << 
823         theLambda->adjustMomentumFromEnergy(); << 
824         theLambda->setPotentialEnergy(0.);     << 
825         theA -= theLambda->getA();             << 
826         theS -= theLambda->getS();             << 
827         toEject.push_back(theLambda);          << 
828       }                                        << 
829     }                                             523     }
830     for(ParticleIter i=toEject.begin(), e=toEj << 
831       theStore->particleHasBeenEjected(*i);    << 
832       theStore->addToOutgoing(*i);             << 
833       (*i)->setParticleBias(Particle::getTotal << 
834     }                                          << 
835     return (G4int)toEject.size();              << 
836   }                                            << 
837                                                << 
838   G4bool Nucleus::emitInsideKaon() {           << 
839     /* Forcing emissions of all Kaon (not anti << 
840      * This probably violates energy conservat << 
841      * (although the computation of the recoil << 
842      * might sweep this under the carpet).     << 
843      */                                        << 
844     INCL_DEBUG("Forcing emissions of all Kaon  << 
845                                                << 
846     // Emit the Kaon with this kinetic energy  << 
847     const G4double tinyEnergy = 0.1; // MeV    << 
848                                                   524 
849     // Push out the emitted kaon               << 525     // Add the geometrical spectators to the Z and A count
850     ParticleList const &inside = theStore->get << 526     if(theProjectileRemnant) {
851     ParticleList toEject;                      << 527       outZ += theProjectileRemnant->getZ();
852     for(ParticleIter i=inside.begin(), e=insid << 528       outA += theProjectileRemnant->getA();
853       if((*i)->isKaon()) {                     << 
854         Particle * const theKaon = *i;         << 
855         INCL_DEBUG("Forcing emission of the fo << 
856                    << theKaon->print() << '\n' << 
857         theKaon->setEmissionTime(theStore->get << 
858         // Correction for real masses          << 
859         const G4double theQValueCorrection = t << 
860         const G4double kineticEnergyOutside =  << 
861         theKaon->setTableMass();               << 
862         if(kineticEnergyOutside > 0.0)         << 
863           theKaon->setEnergy(theKaon->getMass( << 
864         else                                   << 
865           theKaon->setEnergy(theKaon->getMass( << 
866         theKaon->adjustMomentumFromEnergy();   << 
867         theKaon->setPotentialEnergy(0.);       << 
868         theZ -= theKaon->getZ();               << 
869         theS -= theKaon->getS();               << 
870         toEject.push_back(theKaon);            << 
871       }                                        << 
872     }                                          << 
873     for(ParticleIter i=toEject.begin(), e=toEj << 
874       theStore->particleHasBeenEjected(*i);    << 
875       theStore->addToOutgoing(*i);             << 
876       (*i)->setParticleBias(Particle::getTotal << 
877     }                                             529     }
878     theNKaon -= 1;                             << 
879     return toEject.size() != 0;                << 
880   }                                            << 
881                                                << 
882   G4bool Nucleus::isEventTransparent() const { << 
883                                                   530 
884     Book const &theBook = theStore->getBook(); << 531     if(outZ!=projectileZ || outA!=projectileA) return false;
885     const G4int nEventCollisions = theBook.get << 
886     const G4int nEventDecays = theBook.getAcce << 
887     const G4int nEventClusters = theBook.getEm << 
888     if(nEventCollisions==0 && nEventDecays==0  << 
889       return true;                             << 
890                                                   532 
891     return false;                              << 533     return true;
892                                                   534 
893   }                                               535   }
894                                                   536 
895   void Nucleus::computeOneNucleonRecoilKinemat    537   void Nucleus::computeOneNucleonRecoilKinematics() {
896     // We should be here only if the nucleus c    538     // We should be here only if the nucleus contains only one nucleon
897 // assert(theStore->getParticles().size()==1);    539 // assert(theStore->getParticles().size()==1);
898                                                   540 
                                                   >> 541     ERROR("Computing one-nucleon recoil kinematics. We should never be here nowadays, cascade should stop earlier than this." << std::endl);
                                                   >> 542 
899     // No excitation energy!                      543     // No excitation energy!
900     theExcitationEnergy = 0.0;                    544     theExcitationEnergy = 0.0;
901                                                   545 
902     // Move the nucleon to the outgoing list      546     // Move the nucleon to the outgoing list
903     Particle *remN = theStore->getParticles().    547     Particle *remN = theStore->getParticles().front();
904     theA -= remN->getA();                         548     theA -= remN->getA();
905     theZ -= remN->getZ();                         549     theZ -= remN->getZ();
906     theS -= remN->getS();                      << 550     theStore->particleHasBeenEjected(remN->getID());
907     theStore->particleHasBeenEjected(remN);    << 
908     theStore->addToOutgoing(remN);                551     theStore->addToOutgoing(remN);
909     remN->setEmissionTime(theStore->getBook(). << 552     remN->setEmissionTime(theStore->getBook()->getCurrentTime());
910                                                   553 
911     // Treat the special case of a remaining d    554     // Treat the special case of a remaining delta
912     if(remN->isDelta()) {                         555     if(remN->isDelta()) {
913       IAvatar *decay = new DecayAvatar(remN, 0    556       IAvatar *decay = new DecayAvatar(remN, 0.0, NULL);
914       FinalState *fs = decay->getFinalState();    557       FinalState *fs = decay->getFinalState();
915       // Eject the pion                           558       // Eject the pion
916       ParticleList const &created = fs->getCre << 559       ParticleList created = fs->getCreatedParticles();
917       for(ParticleIter j=created.begin(), e=cr << 560       for(ParticleIter j = created.begin(); j != created.end(); ++j)
918         theStore->addToOutgoing(*j);              561         theStore->addToOutgoing(*j);
919       delete fs;                                  562       delete fs;
920       delete decay;                               563       delete decay;
921     }                                             564     }
922                                                   565 
923     // Do different things depending on how ma    566     // Do different things depending on how many outgoing particles we have
924     ParticleList const &outgoing = theStore->g << 567     ParticleList outgoing = theStore->getOutgoingParticles();
925     if(outgoing.size() == 2) {                    568     if(outgoing.size() == 2) {
926                                                   569 
927       INCL_DEBUG("Two particles in the outgoin << 570       DEBUG("Two particles in the outgoing channel, applying exact two-body kinematics" << std::endl);
928                                                   571 
929       // Can apply exact 2-body kinematics her    572       // Can apply exact 2-body kinematics here. Keep the CM emission angle of
930       // the first particle.                      573       // the first particle.
931       Particle *p1 = outgoing.front(), *p2 = o    574       Particle *p1 = outgoing.front(), *p2 = outgoing.back();
932       const ThreeVector aBoostVector = incomin    575       const ThreeVector aBoostVector = incomingMomentum / initialEnergy;
933       // Boost to the initial CM                  576       // Boost to the initial CM
934       p1->boost(aBoostVector);                    577       p1->boost(aBoostVector);
935       const G4double sqrts = std::sqrt(initial    578       const G4double sqrts = std::sqrt(initialEnergy*initialEnergy - incomingMomentum.mag2());
936       const G4double pcm = KinematicsUtils::mo    579       const G4double pcm = KinematicsUtils::momentumInCM(sqrts, p1->getMass(), p2->getMass());
937       const G4double scale = pcm/(p1->getMomen    580       const G4double scale = pcm/(p1->getMomentum().mag());
938       // Reset the momenta                        581       // Reset the momenta
939       p1->setMomentum(p1->getMomentum()*scale)    582       p1->setMomentum(p1->getMomentum()*scale);
940       p2->setMomentum(-p1->getMomentum());        583       p2->setMomentum(-p1->getMomentum());
941       p1->adjustEnergyFromMomentum();             584       p1->adjustEnergyFromMomentum();
942       p2->adjustEnergyFromMomentum();             585       p2->adjustEnergyFromMomentum();
943       // Unboost                                  586       // Unboost
944       p1->boost(-aBoostVector);                   587       p1->boost(-aBoostVector);
945       p2->boost(-aBoostVector);                   588       p2->boost(-aBoostVector);
946                                                   589 
947     } else {                                      590     } else {
948                                                   591 
949       INCL_DEBUG("Trying to adjust final-state << 592       DEBUG("Trying to adjust final-state momenta to achieve energy and momentum conservation" << std::endl);
950                                                   593 
951       const G4int maxIterations=8;                594       const G4int maxIterations=8;
952       G4double totalEnergy, energyScale;          595       G4double totalEnergy, energyScale;
953       G4double val=1.E+100, oldVal=1.E+100, ol    596       G4double val=1.E+100, oldVal=1.E+100, oldOldVal=1.E+100, oldOldOldVal;
954       ThreeVector totalMomentum, deltaP;          597       ThreeVector totalMomentum, deltaP;
955       std::vector<ThreeVector> minMomenta;  //    598       std::vector<ThreeVector> minMomenta;  // use it to store the particle momenta that minimize the merit function
956                                                   599 
957       // Reserve the vector size                  600       // Reserve the vector size
958       minMomenta.reserve(outgoing.size());        601       minMomenta.reserve(outgoing.size());
959                                                   602 
960       // Compute the initial total momentum       603       // Compute the initial total momentum
961       totalMomentum.setX(0.0);                    604       totalMomentum.setX(0.0);
962       totalMomentum.setY(0.0);                    605       totalMomentum.setY(0.0);
963       totalMomentum.setZ(0.0);                    606       totalMomentum.setZ(0.0);
964       for(ParticleIter i=outgoing.begin(), e=o << 607       for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i)
965         totalMomentum += (*i)->getMomentum();     608         totalMomentum += (*i)->getMomentum();
966                                                   609 
967       // Compute the initial total energy         610       // Compute the initial total energy
968       totalEnergy = 0.0;                          611       totalEnergy = 0.0;
969       for(ParticleIter i=outgoing.begin(), e=o << 612       for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i)
970         totalEnergy += (*i)->getEnergy();         613         totalEnergy += (*i)->getEnergy();
971                                                   614 
972       // Iterative algorithm starts here:         615       // Iterative algorithm starts here:
973       for(G4int iterations=0; iterations < max    616       for(G4int iterations=0; iterations < maxIterations; ++iterations) {
974                                                   617 
975         // Save the old merit-function values     618         // Save the old merit-function values
976         oldOldOldVal = oldOldVal;                 619         oldOldOldVal = oldOldVal;
977         oldOldVal = oldVal;                       620         oldOldVal = oldVal;
978         oldVal = val;                             621         oldVal = val;
979                                                   622 
980         if(iterations%2 == 0) {                   623         if(iterations%2 == 0) {
981           INCL_DEBUG("Momentum step" << '\n'); << 624           DEBUG("Momentum step" << std::endl);
982           // Momentum step: modify all the par    625           // Momentum step: modify all the particle momenta
983           deltaP = incomingMomentum - totalMom    626           deltaP = incomingMomentum - totalMomentum;
984           G4double pOldTot = 0.0;                 627           G4double pOldTot = 0.0;
985           for(ParticleIter i=outgoing.begin(), << 628           for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i)
986             pOldTot += (*i)->getMomentum().mag    629             pOldTot += (*i)->getMomentum().mag();
987           for(ParticleIter i=outgoing.begin(), << 630           for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i) {
988             const ThreeVector mom = (*i)->getM    631             const ThreeVector mom = (*i)->getMomentum();
989             (*i)->setMomentum(mom + deltaP*mom    632             (*i)->setMomentum(mom + deltaP*mom.mag()/pOldTot);
990             (*i)->adjustEnergyFromMomentum();     633             (*i)->adjustEnergyFromMomentum();
991           }                                       634           }
992         } else {                                  635         } else {
993           INCL_DEBUG("Energy step" << '\n');   << 636           DEBUG("Energy step" << std::endl);
994           // Energy step: modify all the parti    637           // Energy step: modify all the particle momenta
995           energyScale = initialEnergy/totalEne    638           energyScale = initialEnergy/totalEnergy;
996           for(ParticleIter i=outgoing.begin(), << 639           for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i) {
997             const ThreeVector mom = (*i)->getM    640             const ThreeVector mom = (*i)->getMomentum();
998             G4double pScale = ((*i)->getEnergy    641             G4double pScale = ((*i)->getEnergy()*energyScale - std::pow((*i)->getMass(),2))/mom.mag2();
999             if(pScale>0) {                        642             if(pScale>0) {
1000               (*i)->setEnergy((*i)->getEnergy    643               (*i)->setEnergy((*i)->getEnergy()*energyScale);
1001               (*i)->adjustMomentumFromEnergy(    644               (*i)->adjustMomentumFromEnergy();
1002             }                                    645             }
1003           }                                      646           }
1004         }                                        647         }
1005                                                  648 
1006         // Compute the current total momentum    649         // Compute the current total momentum and energy
1007         totalMomentum.setX(0.0);                 650         totalMomentum.setX(0.0);
1008         totalMomentum.setY(0.0);                 651         totalMomentum.setY(0.0);
1009         totalMomentum.setZ(0.0);                 652         totalMomentum.setZ(0.0);
1010         totalEnergy = 0.0;                       653         totalEnergy = 0.0;
1011         for(ParticleIter i=outgoing.begin(),  << 654         for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i) {
1012           totalMomentum += (*i)->getMomentum(    655           totalMomentum += (*i)->getMomentum();
1013           totalEnergy += (*i)->getEnergy();      656           totalEnergy += (*i)->getEnergy();
1014         }                                        657         }
1015                                                  658 
1016         // Merit factor                          659         // Merit factor
1017         val = std::pow(totalEnergy - initialE    660         val = std::pow(totalEnergy - initialEnergy,2) +
1018           0.25*(totalMomentum - incomingMomen    661           0.25*(totalMomentum - incomingMomentum).mag2();
1019         INCL_DEBUG("Merit function: val=" <<  << 662         DEBUG("Merit function: val=" << val << ", oldVal=" << oldVal << ", oldOldVal=" << oldOldVal << ", oldOldOldVal=" << oldOldOldVal << std::endl);
1020                                                  663 
1021         // Store the minimum                     664         // Store the minimum
1022         if(val < oldVal) {                       665         if(val < oldVal) {
1023           INCL_DEBUG("New minimum found, stor << 666           DEBUG("New minimum found, storing the particle momenta" << std::endl);
1024           minMomenta.clear();                    667           minMomenta.clear();
1025           for(ParticleIter i=outgoing.begin() << 668           for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i)
1026             minMomenta.push_back((*i)->getMom    669             minMomenta.push_back((*i)->getMomentum());
1027         }                                        670         }
1028                                                  671 
1029         // Stop the algorithm if the search d    672         // Stop the algorithm if the search diverges
1030         if(val > oldOldVal && oldVal > oldOld    673         if(val > oldOldVal && oldVal > oldOldOldVal) {
1031           INCL_DEBUG("Search is diverging, br << 674           DEBUG("Search is diverging, breaking out of the iteration loop: val=" << val << ", oldVal=" << oldVal << ", oldOldVal=" << oldOldVal << ", oldOldOldVal=" << oldOldOldVal << std::endl);
1032           break;                                 675           break;
1033         }                                        676         }
1034       }                                          677       }
1035                                                  678 
1036       // We should have made at least one suc    679       // We should have made at least one successful iteration here
1037 // assert(minMomenta.size()==outgoing.size())    680 // assert(minMomenta.size()==outgoing.size());
1038                                                  681 
1039       // Apply the optimal momenta               682       // Apply the optimal momenta
1040       INCL_DEBUG("Applying the solution" << ' << 683       DEBUG("Applying the solution" << std::endl);
1041       std::vector<ThreeVector>::const_iterato    684       std::vector<ThreeVector>::const_iterator v = minMomenta.begin();
1042       for(ParticleIter i=outgoing.begin(), e= << 685       for(ParticleIter i=outgoing.begin(); i!=outgoing.end(); ++i, ++v) {
1043         (*i)->setMomentum(*v);                   686         (*i)->setMomentum(*v);
1044         (*i)->adjustEnergyFromMomentum();        687         (*i)->adjustEnergyFromMomentum();
1045         INCL_DATABLOCK((*i)->print());        << 688         DATABLOCK((*i)->print());
1046       }                                          689       }
1047                                                  690 
1048     }                                            691     }
1049                                                  692 
1050   }                                              693   }
1051                                                  694 
1052   void Nucleus::fillEventInfo(EventInfo *even    695   void Nucleus::fillEventInfo(EventInfo *eventInfo) {
1053     eventInfo->nParticles = 0;                   696     eventInfo->nParticles = 0;
1054     G4bool isNucleonAbsorption = false;          697     G4bool isNucleonAbsorption = false;
                                                   >> 698 
1055     G4bool isPionAbsorption = false;             699     G4bool isPionAbsorption = false;
1056     // It is possible to have pion absorption    700     // It is possible to have pion absorption event only if the
1057     // projectile is pion.                       701     // projectile is pion.
1058     if(eventInfo->projectileType == PiPlus ||    702     if(eventInfo->projectileType == PiPlus ||
1059        eventInfo->projectileType == PiMinus |    703        eventInfo->projectileType == PiMinus ||
1060        eventInfo->projectileType == PiZero) {    704        eventInfo->projectileType == PiZero) {
1061       isPionAbsorption = true;                   705       isPionAbsorption = true;
1062     }                                            706     }
1063                                                  707 
1064     // Forced CN                                 708     // Forced CN
1065     eventInfo->forcedCompoundNucleus = tryCN;    709     eventInfo->forcedCompoundNucleus = tryCN;
1066                                                  710 
1067     // Outgoing particles                        711     // Outgoing particles
1068     ParticleList const &outgoingParticles = g << 712     ParticleList outgoingParticles = getStore()->getOutgoingParticles();
1069                                                  713 
1070     // Check if we have a nucleon absorption     714     // Check if we have a nucleon absorption event: nucleon projectile
1071     // and no ejected particles.                 715     // and no ejected particles.
1072     if(outgoingParticles.size() == 0 &&          716     if(outgoingParticles.size() == 0 &&
1073        (eventInfo->projectileType == Proton |    717        (eventInfo->projectileType == Proton ||
1074     eventInfo->projectileType == Neutron)) {  << 718   eventInfo->projectileType == Neutron)) {
1075       isNucleonAbsorption = true;                719       isNucleonAbsorption = true;
1076     }                                            720     }
1077                                                  721 
1078     // Reset the remnant counter                 722     // Reset the remnant counter
1079     eventInfo->nRemnants = 0;                    723     eventInfo->nRemnants = 0;
1080     eventInfo->history.clear();                  724     eventInfo->history.clear();
1081                                                  725 
1082     for(ParticleIter i=outgoingParticles.begi << 726     for( ParticleIter i = outgoingParticles.begin(); i != outgoingParticles.end(); ++i ) {
                                                   >> 727       // If the particle is a cluster and has excitation energy, treat it as a cluster
                                                   >> 728       if((*i)->isCluster()) {
                                                   >> 729         Cluster const * const c = dynamic_cast<Cluster *>(*i);
                                                   >> 730 // assert(c);
                                                   >> 731 #ifdef INCLXX_IN_GEANT4_MODE
                                                   >> 732         if(!c)
                                                   >> 733           continue;
                                                   >> 734 #endif
                                                   >> 735         const G4double eStar = c->getExcitationEnergy();
                                                   >> 736         if(std::abs(eStar)>1E-10) {
                                                   >> 737           if(eStar<0.) {
                                                   >> 738             WARN("Negative excitation energy in outgoing cluster! EStar = " << eStar << std::endl);
                                                   >> 739           }
                                                   >> 740           eventInfo->ARem[eventInfo->nRemnants] = c->getA();
                                                   >> 741           eventInfo->ZRem[eventInfo->nRemnants] = c->getZ();
                                                   >> 742           eventInfo->EStarRem[eventInfo->nRemnants] = eStar;
                                                   >> 743           ThreeVector remnantSpin = c->getSpin();
                                                   >> 744           Float_t remnantSpinMag;
                                                   >> 745           if(eventInfo->ARem[eventInfo->nRemnants]%2==0) { // even-A nucleus
                                                   >> 746             remnantSpinMag = (G4int) (remnantSpin.mag()/PhysicalConstants::hc + 0.5);
                                                   >> 747           } else { // odd-A nucleus
                                                   >> 748             remnantSpinMag = ((G4int) (remnantSpin.mag()/PhysicalConstants::hc)) + 0.5;
                                                   >> 749           }
                                                   >> 750           remnantSpin *= remnantSpinMag/remnantSpin.mag();
                                                   >> 751           eventInfo->JRem[eventInfo->nRemnants] = remnantSpinMag;
                                                   >> 752           eventInfo->jxRem[eventInfo->nRemnants] = remnantSpin.getX();
                                                   >> 753           eventInfo->jyRem[eventInfo->nRemnants] = remnantSpin.getY();
                                                   >> 754           eventInfo->jzRem[eventInfo->nRemnants] = remnantSpin.getZ();
                                                   >> 755           eventInfo->EKinRem[eventInfo->nRemnants] = c->getKineticEnergy();
                                                   >> 756           ThreeVector mom = c->getMomentum();
                                                   >> 757           eventInfo->pxRem[eventInfo->nRemnants] = mom.getX();
                                                   >> 758           eventInfo->pyRem[eventInfo->nRemnants] = mom.getY();
                                                   >> 759           eventInfo->pzRem[eventInfo->nRemnants] = mom.getZ();
                                                   >> 760           eventInfo->thetaRem[eventInfo->nRemnants] = Math::toDegrees(mom.theta());
                                                   >> 761           eventInfo->phiRem[eventInfo->nRemnants] = Math::toDegrees(mom.phi());
                                                   >> 762           eventInfo->nRemnants++;
                                                   >> 763           continue; // don't add it as a particle
                                                   >> 764         }
                                                   >> 765       }
                                                   >> 766 
1083       // We have a pion absorption event only    767       // We have a pion absorption event only if the projectile is
1084       // pion and there are no ejected pions.    768       // pion and there are no ejected pions.
1085       if(isPionAbsorption) {                     769       if(isPionAbsorption) {
1086         if((*i)->isPion()) {                     770         if((*i)->isPion()) {
1087           isPionAbsorption = false;              771           isPionAbsorption = false;
1088         }                                        772         }
1089       }                                          773       }
1090                                               << 774       eventInfo->A[eventInfo->nParticles] = (*i)->getA();
1091       eventInfo->ParticleBias[eventInfo->nPar << 775       eventInfo->Z[eventInfo->nParticles] = (*i)->getZ();
1092                                               << 
1093 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1094       eventInfo->A[eventInfo->nParticles] = ( << 
1095       eventInfo->Z[eventInfo->nParticles] = ( << 
1096       eventInfo->S[eventInfo->nParticles] = ( << 
1097 #else                                         << 
1098       eventInfo->A[eventInfo->nParticles] = ( << 
1099       eventInfo->Z[eventInfo->nParticles] = ( << 
1100       eventInfo->S[eventInfo->nParticles] = ( << 
1101 #endif                                        << 
1102       eventInfo->emissionTime[eventInfo->nPar    776       eventInfo->emissionTime[eventInfo->nParticles] = (*i)->getEmissionTime();
1103       eventInfo->EKin[eventInfo->nParticles]     777       eventInfo->EKin[eventInfo->nParticles] = (*i)->getKineticEnergy();
1104       ThreeVector mom = (*i)->getMomentum();     778       ThreeVector mom = (*i)->getMomentum();
1105       eventInfo->px[eventInfo->nParticles] =     779       eventInfo->px[eventInfo->nParticles] = mom.getX();
1106       eventInfo->py[eventInfo->nParticles] =     780       eventInfo->py[eventInfo->nParticles] = mom.getY();
1107       eventInfo->pz[eventInfo->nParticles] =     781       eventInfo->pz[eventInfo->nParticles] = mom.getZ();
1108       eventInfo->theta[eventInfo->nParticles]    782       eventInfo->theta[eventInfo->nParticles] = Math::toDegrees(mom.theta());
1109       eventInfo->phi[eventInfo->nParticles] =    783       eventInfo->phi[eventInfo->nParticles] = Math::toDegrees(mom.phi());
1110       eventInfo->origin[eventInfo->nParticles    784       eventInfo->origin[eventInfo->nParticles] = -1;
1111 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1112       eventInfo->parentResonancePDGCode[event << 
1113       eventInfo->parentResonanceID[eventInfo- << 
1114 #endif                                        << 
1115       eventInfo->history.push_back("");          785       eventInfo->history.push_back("");
1116       if ((*i)->getType() != Composite) {     << 
1117         ParticleSpecies pt((*i)->getType());  << 
1118         eventInfo->PDGCode[eventInfo->nPartic << 
1119       }                                       << 
1120       else {                                  << 
1121         ParticleSpecies pt((*i)->getA(), (*i) << 
1122         eventInfo->PDGCode[eventInfo->nPartic << 
1123       }                                       << 
1124       eventInfo->nParticles++;                   786       eventInfo->nParticles++;
1125     }                                            787     }
1126     eventInfo->nucleonAbsorption = isNucleonA    788     eventInfo->nucleonAbsorption = isNucleonAbsorption;
1127     eventInfo->pionAbsorption = isPionAbsorpt    789     eventInfo->pionAbsorption = isPionAbsorption;
1128     eventInfo->nCascadeParticles = eventInfo-    790     eventInfo->nCascadeParticles = eventInfo->nParticles;
1129                                                  791 
1130     // Projectile-like remnant characteristic << 792     // Remnant characteristics
1131     if(theProjectileRemnant && theProjectileR << 
1132 #ifdef INCLXX_IN_GEANT4_MODE                  << 
1133       eventInfo->ARem[eventInfo->nRemnants] = << 
1134       eventInfo->ZRem[eventInfo->nRemnants] = << 
1135       eventInfo->SRem[eventInfo->nRemnants] = << 
1136 #else                                         << 
1137       eventInfo->ARem[eventInfo->nRemnants] = << 
1138       eventInfo->ZRem[eventInfo->nRemnants] = << 
1139       eventInfo->SRem[eventInfo->nRemnants] = << 
1140 #endif                                        << 
1141       G4double eStar = theProjectileRemnant-> << 
1142       if(std::abs(eStar)<1E-10)               << 
1143         eStar = 0.0; // blame rounding and se << 
1144       eventInfo->EStarRem[eventInfo->nRemnant << 
1145       if(eventInfo->EStarRem[eventInfo->nRemn << 
1146     INCL_WARN("Negative excitation energy in  << 
1147       }                                       << 
1148       const ThreeVector &spin = theProjectile << 
1149       if(eventInfo->ARem[eventInfo->nRemnants << 
1150     eventInfo->JRem[eventInfo->nRemnants] = ( << 
1151       } else { // odd-A nucleus               << 
1152     eventInfo->JRem[eventInfo->nRemnants] = ( << 
1153       }                                       << 
1154       eventInfo->EKinRem[eventInfo->nRemnants << 
1155       const ThreeVector &mom = theProjectileR << 
1156       eventInfo->pxRem[eventInfo->nRemnants]  << 
1157       eventInfo->pyRem[eventInfo->nRemnants]  << 
1158       eventInfo->pzRem[eventInfo->nRemnants]  << 
1159       eventInfo->jxRem[eventInfo->nRemnants]  << 
1160       eventInfo->jyRem[eventInfo->nRemnants]  << 
1161       eventInfo->jzRem[eventInfo->nRemnants]  << 
1162       eventInfo->thetaRem[eventInfo->nRemnant << 
1163       eventInfo->phiRem[eventInfo->nRemnants] << 
1164       eventInfo->nRemnants++;                 << 
1165     }                                         << 
1166                                               << 
1167     // Target-like remnant characteristics    << 
1168     if(hasRemnant()) {                           793     if(hasRemnant()) {
1169 #ifdef INCLXX_IN_GEANT4_MODE                  << 794       eventInfo->ARem[eventInfo->nRemnants] = getA();
1170       eventInfo->ARem[eventInfo->nRemnants] = << 795       eventInfo->ZRem[eventInfo->nRemnants] = getZ();
1171       eventInfo->ZRem[eventInfo->nRemnants] = << 
1172       eventInfo->SRem[eventInfo->nRemnants] = << 
1173 #else                                         << 
1174       eventInfo->ARem[eventInfo->nRemnants] = << 
1175       eventInfo->ZRem[eventInfo->nRemnants] = << 
1176       eventInfo->SRem[eventInfo->nRemnants] = << 
1177 #endif                                        << 
1178       eventInfo->EStarRem[eventInfo->nRemnant    796       eventInfo->EStarRem[eventInfo->nRemnants] = getExcitationEnergy();
1179       if(eventInfo->EStarRem[eventInfo->nRemn    797       if(eventInfo->EStarRem[eventInfo->nRemnants]<0.) {
1180     INCL_WARN("Negative excitation energy in  << 798   WARN("Negative excitation energy! EStarRem = " << eventInfo->EStarRem[eventInfo->nRemnants] << std::endl);
1181       }                                          799       }
1182       const ThreeVector &spin = getSpin();    << 
1183       if(eventInfo->ARem[eventInfo->nRemnants    800       if(eventInfo->ARem[eventInfo->nRemnants]%2==0) { // even-A nucleus
1184     eventInfo->JRem[eventInfo->nRemnants] = ( << 801   eventInfo->JRem[eventInfo->nRemnants] = (G4int) (getSpin().mag()/PhysicalConstants::hc + 0.5);
1185       } else { // odd-A nucleus                  802       } else { // odd-A nucleus
1186     eventInfo->JRem[eventInfo->nRemnants] = ( << 803   eventInfo->JRem[eventInfo->nRemnants] = ((G4int) (getSpin().mag()/PhysicalConstants::hc)) + 0.5;
1187       }                                          804       }
1188       eventInfo->EKinRem[eventInfo->nRemnants    805       eventInfo->EKinRem[eventInfo->nRemnants] = getKineticEnergy();
1189       const ThreeVector &mom = getMomentum(); << 806       ThreeVector mom = getMomentum();
1190       eventInfo->pxRem[eventInfo->nRemnants]     807       eventInfo->pxRem[eventInfo->nRemnants] = mom.getX();
1191       eventInfo->pyRem[eventInfo->nRemnants]     808       eventInfo->pyRem[eventInfo->nRemnants] = mom.getY();
1192       eventInfo->pzRem[eventInfo->nRemnants]     809       eventInfo->pzRem[eventInfo->nRemnants] = mom.getZ();
1193       eventInfo->jxRem[eventInfo->nRemnants]  << 
1194       eventInfo->jyRem[eventInfo->nRemnants]  << 
1195       eventInfo->jzRem[eventInfo->nRemnants]  << 
1196       eventInfo->thetaRem[eventInfo->nRemnant    810       eventInfo->thetaRem[eventInfo->nRemnants] = Math::toDegrees(mom.theta());
1197       eventInfo->phiRem[eventInfo->nRemnants]    811       eventInfo->phiRem[eventInfo->nRemnants] = Math::toDegrees(mom.phi());
1198       eventInfo->nRemnants++;                    812       eventInfo->nRemnants++;
1199     }                                            813     }
1200                                                  814 
1201     // Global counters, flags, etc.              815     // Global counters, flags, etc.
1202     Book const &theBook = theStore->getBook() << 816     eventInfo->nCollisions = getStore()->getBook()->getAcceptedCollisions();
1203     eventInfo->nCollisions = theBook.getAccep << 817     eventInfo->nBlockedCollisions = getStore()->getBook()->getBlockedCollisions();
1204     eventInfo->nBlockedCollisions = theBook.g << 818     eventInfo->nDecays = getStore()->getBook()->getAcceptedDecays();
1205     eventInfo->nDecays = theBook.getAcceptedD << 819     eventInfo->nBlockedDecays = getStore()->getBook()->getBlockedDecays();
1206     eventInfo->nBlockedDecays = theBook.getBl << 820     eventInfo->firstCollisionTime = getStore()->getBook()->getFirstCollisionTime();
1207     eventInfo->firstCollisionTime = theBook.g << 821     eventInfo->firstCollisionXSec = getStore()->getBook()->getFirstCollisionXSec();
1208     eventInfo->firstCollisionXSec = theBook.g << 822     eventInfo->nReflectionAvatars = getStore()->getBook()->getAvatars(SurfaceAvatarType);
1209     eventInfo->firstCollisionSpectatorPositio << 823     eventInfo->nCollisionAvatars = getStore()->getBook()->getAvatars(CollisionAvatarType);
1210     eventInfo->firstCollisionSpectatorMomentu << 824     eventInfo->nDecayAvatars = getStore()->getBook()->getAvatars(DecayAvatarType);
1211     eventInfo->firstCollisionIsElastic = theB << 
1212     eventInfo->nReflectionAvatars = theBook.g << 
1213     eventInfo->nCollisionAvatars = theBook.ge << 
1214     eventInfo->nDecayAvatars = theBook.getAva << 
1215     eventInfo->nEnergyViolationInteraction =  << 
1216   }                                              825   }
1217                                                  826 
1218                                               << 
1219                                               << 
1220   Nucleus::ConservationBalance Nucleus::getCo    827   Nucleus::ConservationBalance Nucleus::getConservationBalance(const EventInfo &theEventInfo, const G4bool afterRecoil) const {
1221     ConservationBalance theBalance;              828     ConservationBalance theBalance;
1222     // Initialise balance variables with the     829     // Initialise balance variables with the incoming values
1223     INCL_DEBUG("theEventInfo " << theEventInf << 
1224     theBalance.Z = theEventInfo.Zp + theEvent    830     theBalance.Z = theEventInfo.Zp + theEventInfo.Zt;
1225     theBalance.A = theEventInfo.Ap + theEvent    831     theBalance.A = theEventInfo.Ap + theEventInfo.At;
1226     theBalance.S = theEventInfo.Sp + theEvent << 832 
1227     INCL_DEBUG("theBalance Z and A " << theBa << 
1228     theBalance.energy = getInitialEnergy();      833     theBalance.energy = getInitialEnergy();
1229     theBalance.momentum = getIncomingMomentum    834     theBalance.momentum = getIncomingMomentum();
1230                                                  835 
1231     // Process outgoing particles                836     // Process outgoing particles
1232     ParticleList const &outgoingParticles = t << 837     ParticleList outgoingParticles = theStore->getOutgoingParticles();
1233     for(ParticleIter i=outgoingParticles.begi << 838     for( ParticleIter i = outgoingParticles.begin(); i != outgoingParticles.end(); ++i ) {
1234       theBalance.Z -= (*i)->getZ();              839       theBalance.Z -= (*i)->getZ();
1235       theBalance.A -= (*i)->getA();              840       theBalance.A -= (*i)->getA();
1236       theBalance.S -= (*i)->getS();           << 
1237       // For outgoing clusters, the total ene    841       // For outgoing clusters, the total energy automatically includes the
1238       // excitation energy                       842       // excitation energy
1239       theBalance.energy -= (*i)->getEnergy();    843       theBalance.energy -= (*i)->getEnergy(); // Note that outgoing particles should have the real mass
1240       theBalance.momentum -= (*i)->getMomentu    844       theBalance.momentum -= (*i)->getMomentum();
1241     }                                            845     }
1242                                                  846 
1243     // Projectile-like remnant contribution,  << 847     // Remnant contribution, if present
1244     if(theProjectileRemnant && theProjectileR << 
1245       theBalance.Z -= theProjectileRemnant->g << 
1246       theBalance.A -= theProjectileRemnant->g << 
1247       theBalance.S -= theProjectileRemnant->g << 
1248       theBalance.energy -= ParticleTable::get << 
1249         theProjectileRemnant->getExcitationEn << 
1250       theBalance.energy -= theProjectileRemna << 
1251       theBalance.momentum -= theProjectileRem << 
1252     }                                         << 
1253                                               << 
1254     // Target-like remnant contribution, if p << 
1255     if(hasRemnant()) {                           848     if(hasRemnant()) {
1256       theBalance.Z -= getZ();                    849       theBalance.Z -= getZ();
1257       theBalance.A -= getA();                    850       theBalance.A -= getA();
1258       theBalance.S -= getS();                 << 851       theBalance.energy -= ParticleTable::getTableMass(getA(),getZ()) +
1259       theBalance.energy -= ParticleTable::get << 
1260         getExcitationEnergy();                   852         getExcitationEnergy();
1261       if(afterRecoil)                            853       if(afterRecoil)
1262         theBalance.energy -= getKineticEnergy    854         theBalance.energy -= getKineticEnergy();
1263       theBalance.momentum -= getMomentum();      855       theBalance.momentum -= getMomentum();
1264     }                                            856     }
1265                                                  857 
1266     return theBalance;                           858     return theBalance;
1267   }                                              859   }
1268                                                  860 
1269   void Nucleus::useFusionKinematics() {          861   void Nucleus::useFusionKinematics() {
1270     setEnergy(initialEnergy);                    862     setEnergy(initialEnergy);
1271     setMomentum(incomingMomentum);               863     setMomentum(incomingMomentum);
1272     setSpin(incomingAngularMomentum);            864     setSpin(incomingAngularMomentum);
1273     theExcitationEnergy = std::sqrt(theEnergy    865     theExcitationEnergy = std::sqrt(theEnergy*theEnergy-theMomentum.mag2()) - getTableMass();
1274     setMass(getTableMass() + theExcitationEne    866     setMass(getTableMass() + theExcitationEnergy);
1275   }                                              867   }
1276                                                  868 
1277   void Nucleus::finalizeProjectileRemnant(con    869   void Nucleus::finalizeProjectileRemnant(const G4double anEmissionTime) {
1278     // Deal with the projectile remnant          870     // Deal with the projectile remnant
1279     const G4int prA = theProjectileRemnant->g << 871     if(theProjectileRemnant->getA()>1) {
1280     if(prA>=1) {                              << 
1281       // Set the mass                            872       // Set the mass
1282       const G4double aMass = theProjectileRem    873       const G4double aMass = theProjectileRemnant->getInvariantMass();
1283       theProjectileRemnant->setMass(aMass);      874       theProjectileRemnant->setMass(aMass);
1284                                                  875 
1285       // Compute the excitation energy from t    876       // Compute the excitation energy from the invariant mass
1286       const G4double anExcitationEnergy = aMa    877       const G4double anExcitationEnergy = aMass
1287         - ParticleTable::getTableMass(prA, th << 878         - ParticleTable::getTableMass(theProjectileRemnant->getA(), theProjectileRemnant->getZ());
1288                                                  879 
1289       // Set the excitation energy               880       // Set the excitation energy
1290       theProjectileRemnant->setExcitationEner    881       theProjectileRemnant->setExcitationEnergy(anExcitationEnergy);
1291                                                  882 
1292       // No spin!                             << 883       // Set the spin
1293       theProjectileRemnant->setSpin(ThreeVect << 884       theProjectileRemnant->setSpin(DeJongSpin::shoot(theProjectileRemnant->getNumberStoredComponents(), theProjectileRemnant->getA()));
1294                                                  885 
1295       // Set the emission time                   886       // Set the emission time
1296       theProjectileRemnant->setEmissionTime(a    887       theProjectileRemnant->setEmissionTime(anEmissionTime);
1297     }                                         << 888 
                                                   >> 889       // Put it in the outgoing list
                                                   >> 890       theStore->addToOutgoing(theProjectileRemnant);
                                                   >> 891 
                                                   >> 892       // NULL theProjectileRemnant
                                                   >> 893       theProjectileRemnant = NULL;
                                                   >> 894     } else if(theProjectileRemnant->getA()==1) {
                                                   >> 895       // Put the nucleon in the outgoing list
                                                   >> 896       Particle *theNucleon = theProjectileRemnant->getParticles().front();
                                                   >> 897       theStore->addToOutgoing(theNucleon);
                                                   >> 898       // Delete the remnant
                                                   >> 899       deleteProjectileRemnant();
                                                   >> 900     } else
                                                   >> 901       deleteProjectileRemnant();
1298   }                                              902   }
1299                                                  903 
1300 }                                                904 }
1301                                                  905 
1302 #endif                                           906 #endif
1303                                                  907