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 10.3.p2)


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