Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/particle_hp/src/G4ParticleHPFinalState.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/particle_hp/src/G4ParticleHPFinalState.cc (Version 11.3.0) and /processes/hadronic/models/particle_hp/src/G4ParticleHPFinalState.cc (Version 11.1)


  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 //                                                 26 //
 27 // 080721 Create adjust_final_state method by  <<  27 //080721 Create adjust_final_state method by T. Koi
 28 // 080801 Residual reconstruction with theNDLD <<  28 //080801 Residual reconstruction with theNDLDataA,Z (A, Z, and momentum are adjusted) by T. Koi
 29 // 101110 Set lower limit for gamma energy(1ke <<  29 //101110 Set lower limit for gamma energy(1keV) by T. Koi
 30 // P. Arce, June-2014 Conversion neutron_hp to     30 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
 31 //                                                 31 //
 32                                                    32 
 33 #include "G4ParticleHPFinalState.hh"               33 #include "G4ParticleHPFinalState.hh"
 34                                                    34 
 35 #include "G4Alpha.hh"                          <<  35 #include "G4PhysicalConstants.hh"
 36 #include "G4Deuteron.hh"                       <<  36 #include "G4SystemOfUnits.hh"
 37 #include "G4Gamma.hh"                          << 
 38 #include "G4He3.hh"                            << 
 39 #include "G4IonTable.hh"                           37 #include "G4IonTable.hh"
                                                   >>  38 #include "G4Gamma.hh"
 40 #include "G4Neutron.hh"                            39 #include "G4Neutron.hh"
 41 #include "G4PhysicalConstants.hh"              << 
 42 #include "G4Proton.hh"                             40 #include "G4Proton.hh"
 43 #include "G4RandomDirection.hh"                <<  41 #include "G4Deuteron.hh"
 44 #include "G4SystemOfUnits.hh"                  << 
 45 #include "G4Triton.hh"                             42 #include "G4Triton.hh"
                                                   >>  43 #include "G4He3.hh"
                                                   >>  44 #include "G4Alpha.hh"
 46                                                    45 
 47 G4ParticleHPFinalState::G4ParticleHPFinalState << 
 48 {                                              << 
 49   theProjectile = G4Neutron::Neutron();        << 
 50   theResult.Put(nullptr);                      << 
 51   fManager = G4ParticleHPManager::GetInstance( << 
 52   ionTable = G4IonTable::GetIonTable();        << 
 53 }                                              << 
 54                                                    46 
 55 G4ParticleHPFinalState::~G4ParticleHPFinalStat <<  47 void G4ParticleHPFinalState::adjust_final_state ( G4LorentzVector init_4p_lab )
 56 {                                                  48 {
 57   delete theResult.Get();                      << 
 58 }                                              << 
 59                                                    49 
 60 void G4ParticleHPFinalState::adjust_final_stat <<  50    G4double minimum_energy = 1*keV;
 61 {                                              << 
 62   G4double minimum_energy = 1 * keV;           << 
 63                                                    51 
 64   if (fManager->GetDoNotAdjustFinalState()) re <<  52    if ( G4ParticleHPManager::GetInstance()->GetDoNotAdjustFinalState() ) return;
 65                                                    53 
 66   auto nSecondaries = (G4int)theResult.Get()-> <<  54    G4int nSecondaries = (G4int)theResult.Get()->GetNumberOfSecondaries();
 67                                                    55 
 68   G4int sum_Z = 0;                             <<  56    G4int sum_Z = 0;
 69   G4int sum_A = 0;                             <<  57    G4int sum_A = 0;
 70   G4int max_SecZ = 0;                          <<  58    G4int max_SecZ = 0;
 71   G4int max_SecA = 0;                          <<  59    G4int max_SecA = 0;
 72   G4int imaxA = -1;                            <<  60    G4int imaxA = -1;
 73   for (G4int i = 0; i < nSecondaries; ++i) {   <<  61    for ( G4int i = 0 ; i < nSecondaries ; ++i )
 74     auto ptr = theResult.Get()->GetSecondary(i <<  62    {
 75     sum_Z += ptr->GetAtomicNumber();           <<  63       sum_Z += theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicNumber();
 76     max_SecZ = std::max(max_SecZ, ptr->GetAtom <<  64       max_SecZ = std::max ( max_SecZ , theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicNumber() );
 77     sum_A += ptr->GetAtomicMass();             <<  65       sum_A += theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicMass();
 78     max_SecA = std::max(max_SecA, ptr->GetAtom <<  66       max_SecA = std::max ( max_SecA , theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicMass() );
 79     if (ptr->GetAtomicMass() == max_SecA)      <<  67       if ( theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicMass() == max_SecA ) imaxA = i;
 80       imaxA = i;                               << 
 81 #ifdef G4PHPDEBUG                                  68 #ifdef G4PHPDEBUG
 82     if (fManager->GetDEBUG())                  <<  69       if( std::getenv("G4ParticleHPDebug"))    G4cout << "G4ParticleHPFinalState::adjust_final_stat SECO " << i << " " <<theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetParticleName() << G4endl;
 83       G4cout << "G4ParticleHPFinalState::adjus << 
 84              << ptr->GetParticleName() << G4en << 
 85 #endif                                             70 #endif
 86   }                                            << 
 87                                                    71 
 88   G4ParticleDefinition* resi_pd = nullptr;     <<  72    }
                                                   >>  73 
                                                   >>  74    G4ParticleDefinition* resi_pd = 0;
 89                                                    75 
 90   G4int baseZNew = theBaseZ;                   <<  76    G4double baseZNew = theBaseZ;
 91   G4int baseANew = theBaseA;                   <<  77    G4double baseANew = theBaseA;
 92   if (theProjectile == G4Neutron::Neutron()) { <<  78    if( theProjectile == G4Neutron::Neutron() ) {
 93     baseANew++;                                <<  79      baseANew ++;
 94   }                                            <<  80    } else if( theProjectile == G4Proton::Proton() ) {
 95   else if (theProjectile == G4Proton::Proton() <<  81      baseZNew ++;
 96     baseZNew++;                                <<  82      baseANew ++;
 97     baseANew++;                                <<  83    } else if( theProjectile == G4Deuteron::Deuteron() ) {
 98   }                                            <<  84      baseZNew ++;
 99   else if (theProjectile == G4Deuteron::Deuter <<  85      baseANew += 2;
100     baseZNew++;                                <<  86    } else if( theProjectile == G4Triton::Triton() ) {
101     baseANew += 2;                             <<  87      baseZNew ++;
102   }                                            <<  88      baseANew += 3;
103   else if (theProjectile == G4Triton::Triton() <<  89    } else if( theProjectile == G4He3::He3() ) {
104     baseZNew++;                                <<  90      baseZNew += 2;
105     baseANew += 3;                             <<  91      baseANew += 3;
106   }                                            <<  92    } else if( theProjectile == G4Alpha::Alpha() ) {
107   else if (theProjectile == G4He3::He3()) {    <<  93      baseZNew += 2;
108     baseZNew += 2;                             <<  94      baseANew += 4;
109     baseANew += 3;                             <<  95    }
110   }                                            << 
111   else if (theProjectile == G4Alpha::Alpha())  << 
112     baseZNew += 2;                             << 
113     baseANew += 4;                             << 
114   }                                            << 
115                                                    96 
116 #ifdef G4PHPDEBUG                                  97 #ifdef G4PHPDEBUG
117   if (fManager->GetDEBUG())                    <<  98    if( std::getenv("G4ParticleHPDebug")) G4cout  << "G4ParticleHPFinalState::adjust_final_stat  BaseZ " << baseZNew << " BaseA " << baseANew << " sum_Z " << sum_Z << " sum_A " << sum_A << G4endl;
118     G4cout << "G4ParticleHPFinalState::adjust_ << 
119            << baseANew << " sum_Z " << sum_Z < << 
120 #endif                                             99 #endif
121                                                   100 
122   G4bool needOneMoreSec = false;               << 101    G4bool needOneMoreSec = false;
123   G4ParticleDefinition* oneMoreSec_pd = nullpt << 102    G4ParticleDefinition* oneMoreSec_pd = 0;
124   if (baseZNew == sum_Z && baseANew == sum_A)  << 103    if ( (G4int)(baseZNew - sum_Z) == 0 && (G4int)(baseANew - sum_A) == 0 )
125     // All secondaries are already created;    << 104    {
126     resi_pd = theResult.Get()->GetSecondary(im << 105       //All secondaries are already created;
127   }                                            << 106       resi_pd = theResult.Get()->GetSecondary( imaxA )->GetParticle()->GetDefinition(); 
128   else {                                       << 107    }
129     if (max_SecA >= baseANew - sum_A) {        << 108    else
130       // Most heavy secondary is interpreted a << 109    {
131       resi_pd = theResult.Get()->GetSecondary( << 110       if ( max_SecA >= G4int(baseANew - sum_A) ) 
132       needOneMoreSec = true;                   << 111       {
133     }                                          << 112          //Most heavy secondary is interpreted as residual
134     else {                                     << 113          resi_pd = theResult.Get()->GetSecondary( imaxA )->GetParticle()->GetDefinition(); 
135       // creation of residual is required      << 114          needOneMoreSec = true;
136       resi_pd = ionTable->GetIon(baseZNew - su << 115       }
137     }                                          << 116       else 
138                                                << 117       {
139     if (needOneMoreSec) {                      << 118          //creation of residual is required 
140       if (baseZNew == sum_Z && baseANew == sum << 119   resi_pd = G4IonTable::GetIonTable()->GetIon ( G4int(baseZNew - sum_Z),
141         // In this case, one neutron is added  << 120                                                       G4int(baseANew - sum_A) , 0.0 );
142         if (baseANew - sum_A > 1)              << 121       }
143           G4cout << "More than one neutron is  << 122 
144                  << G4endl;                    << 123       if ( needOneMoreSec )
145         oneMoreSec_pd = G4Neutron::Neutron();  << 124       {
146       }                                        << 125          if ( G4int(baseZNew - sum_Z) == 0 && G4int(baseANew - sum_A) > 0 )
147       else {                                   << 126          {
                                                   >> 127             //In this case, one neutron is added to secondaries 
                                                   >> 128             if ( G4int(baseANew - sum_A) > 1 )
                                                   >> 129               G4cout << "More than one neutron is required for the balance of baryon number!"
                                                   >> 130                      << G4endl;
                                                   >> 131             oneMoreSec_pd = G4Neutron::Neutron();
                                                   >> 132          }
                                                   >> 133          else 
                                                   >> 134          {
148 #ifdef G4PHPDEBUG                                 135 #ifdef G4PHPDEBUG
149         if (fManager->GetDEBUG())              << 136      if( std::getenv("G4ParticleHPDebug")) G4cout << this << "G4ParticleHPFinalState oneMoreSec_pd Z " << baseZNew << " - " << sum_Z << " A " << baseANew << " - " << sum_A << " projectile " << theProjectile->GetParticleName() << G4endl;
150           G4cout << this << "G4ParticleHPFinal << 
151                  << baseZNew << " - " << sum_Z << 
152                  << " A " << baseANew << " - " << 
153                  << theProjectile->GetParticle << 
154 #endif                                            137 #endif
155         oneMoreSec_pd =                        << 138      oneMoreSec_pd = G4IonTable::GetIonTable()->GetIon ( G4int(baseZNew - sum_Z),
156           G4IonTable::GetIonTable()->GetIon(ba << 139                                                                G4int(baseANew - sum_A) , 0.0 );
157         if (oneMoreSec_pd == nullptr) {        << 140      if( !oneMoreSec_pd ) {
158     G4ExceptionDescription ed;                 << 141        G4cerr << this << "G4ParticleHPFinalState oneMoreSec_pd Z " << baseZNew << " - " << sum_Z << " A " << baseANew << " - " << sum_A << " projectile " << theProjectile->GetParticleName() << G4endl;
159           ed << "G4ParticleHPFinalState oneMor << 142        G4Exception("G4ParticleHPFinalState:adjust_final_state",
160                  << " A=" << baseANew << " - " << 143        "Warning",
161                  << theProjectile->GetParticle << 144        JustWarning,
162           G4Exception("G4ParticleHPFinalState: << 145        "No adjustment will be done!");
163                       ed, "No adjustment will  << 146        return;
164           return;                              << 147      }
165         }                                      << 148          }
166       }                                        << 149       }
167     }                                          << 150   
168                                                << 151       if ( resi_pd == 0 )
169     if (resi_pd == nullptr) {                  << 152       {
170       // theNDLDataZ,A has the Z and A of used << 153          // theNDLDataZ,A has the Z and A of used NDL file
171       G4int ndlZNew = theNDLDataZ;             << 154   G4double ndlZNew = theNDLDataZ;
172       G4int ndlANew = theNDLDataA;             << 155   G4double ndlANew = theNDLDataA;
173       if (theProjectile == G4Neutron::Neutron( << 156   if( theProjectile == G4Neutron::Neutron() ) {
174         ndlANew++;                             << 157     ndlANew ++;
175       }                                        << 158   } else if( theProjectile == G4Proton::Proton() ) {
176       else if (theProjectile == G4Proton::Prot << 159     ndlZNew ++;
177         ndlZNew++;                             << 160     ndlANew ++;
178         ndlANew++;                             << 161   } else if( theProjectile == G4Deuteron::Deuteron() ) {
179       }                                        << 162     ndlZNew ++;
180       else if (theProjectile == G4Deuteron::De << 163     ndlANew += 2;
181         ndlZNew++;                             << 164   } else if( theProjectile == G4Triton::Triton() ) {
182         ndlANew += 2;                          << 165     ndlZNew ++;
183       }                                        << 166     ndlANew += 3;
184       else if (theProjectile == G4Triton::Trit << 167   } else if( theProjectile == G4He3::He3() ) {
185         ndlZNew++;                             << 168     ndlZNew += 2;
186         ndlANew += 3;                          << 169     ndlANew += 3;
187       }                                        << 170   } else if( theProjectile == G4Alpha::Alpha() ) {
188       else if (theProjectile == G4He3::He3())  << 171     ndlZNew += 2;
189         ndlZNew += 2;                          << 172     ndlANew += 4;
190         ndlANew += 3;                          << 173   }
191       }                                        << 174         // theNDLDataZ,A has the Z and A of used NDL file
192       else if (theProjectile == G4Alpha::Alpha << 175         if ( G4int(ndlZNew - sum_Z) == 0 && G4int(ndlANew - sum_A) == 0 )
193         ndlZNew += 2;                          << 176         {
194         ndlANew += 4;                          << 177            G4int dif_Z = G4int( theNDLDataZ - theBaseZ );
195       }                                        << 178            G4int dif_A = G4int( theNDLDataA - theBaseA );
196       // theNDLDataZ,A has the Z and A of used << 179            resi_pd = G4IonTable::GetIonTable()->GetIon ( max_SecZ - dif_Z , max_SecA - dif_A , 0.0 );
197       if (ndlZNew == sum_Z && ndlANew == sum_A << 180      if( !resi_pd ) {
198         G4int dif_Z = theNDLDataZ - theBaseZ;  << 181        G4cerr << "G4ParticleHPFinalState resi_pd Z " << max_SecZ << " - " << dif_Z << " A " << max_SecA << " - " << dif_A << " projectile " << theProjectile->GetParticleName() << G4endl;
199         G4int dif_A = theNDLDataA - theBaseA;  << 182        G4Exception("G4ParticleHPFinalState:adjust_final_state",
200         resi_pd = ionTable->GetIon(max_SecZ -  << 183        "Warning",
201         if (resi_pd == nullptr) {              << 184        JustWarning,
202     G4ExceptionDescription ed;                 << 185        "No adjustment will be done!");
203           ed << "resi_pd Z=" << max_SecZ << "  << 186        return;
204                  << max_SecA << " - " << dif_A << 187      }
205                  << theProjectile->GetParticle << 188 
206           G4Exception("G4ParticleHPFinalState: << 189            for ( G4int i = 0 ; i < nSecondaries ; ++i )
207                       ed, "No adjustment will  << 190            {
208           return;                              << 191               if ( theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicNumber() == max_SecZ  
209         }                                      << 192                 && theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition()->GetAtomicMass() == max_SecA )
210                                                << 193               {
211         for (G4int i = 0; i < nSecondaries; ++ << 194                  G4ThreeVector p = theResult.Get()->GetSecondary( i )->GetParticle()->GetMomentum();
212           auto ptr = theResult.Get()->GetSecon << 195                  p = p * resi_pd->GetPDGMass()/ G4IonTable::GetIonTable()->GetIon ( max_SecZ , max_SecA , 0.0 )->GetPDGMass(); 
213           if (ptr->GetDefinition()->GetAtomicN << 196                  theResult.Get()->GetSecondary( i )->GetParticle()->SetDefinition( resi_pd );
214               ptr->GetDefinition()->GetAtomicM << 197                  theResult.Get()->GetSecondary( i )->GetParticle()->SetMomentum( p );
215           {                                    << 198               } 
216             G4ThreeVector p = ptr->GetMomentum << 199            }
217                 / ionTable->GetIon(max_SecZ, m << 
218             ptr->SetDefinition(resi_pd);       << 
219             ptr->SetMomentum(p);               << 
220           }                                    << 
221         }                                         200         }
222       }                                           201       }
223     }                                          << 202    }
224   }                                            << 
225                                                   203 
226   G4LorentzVector secs_4p_lab(0.0);            << 204    G4LorentzVector secs_4p_lab( 0.0 );
227                                                   205 
228   auto n_sec = (G4int)theResult.Get()->GetNumb << 206    G4int n_sec = (G4int)theResult.Get()->GetNumberOfSecondaries();
229   G4double fast = 0;                           << 207    G4double fast = 0;
230   G4double slow = 1;                           << 208    G4double slow = 1;
231   G4int ifast = 0;                             << 209    G4int ifast = 0;
232   G4int islow = 0;                             << 210    G4int islow = 0;
233   G4int ires = -1;                             << 211    G4int ires = -1;
234                                                << 212 
235   for (G4int i = 0; i < n_sec; ++i) {          << 213    for ( G4int i = 0 ; i < n_sec ; ++i )
236     auto ptr = theResult.Get()->GetSecondary(i << 214    {
237     secs_4p_lab += ptr->Get4Momentum();        << 215       secs_4p_lab += theResult.Get()->GetSecondary( i )->GetParticle()->Get4Momentum();
238                                                << 216 
239     G4double beta = 0;                         << 217       G4double beta = 0;
240     if (ptr->GetDefinition() != G4Gamma::Gamma << 218       if ( theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition() != G4Gamma::Gamma() )
241       beta = ptr->Get4Momentum().beta();       << 219       {
242     }                                          << 220          beta = theResult.Get()->GetSecondary( i )->GetParticle()->Get4Momentum().beta(); 
243     else {                                     << 221       }
244       beta = 1.0;                              << 222       else
245     }                                          << 223       {
246                                                << 224          beta = 1;
247     if (ptr->GetDefinition() == resi_pd) ires  << 225       }
248                                                << 226 
249     if (slow > beta && beta != 0) {            << 227       if ( theResult.Get()->GetSecondary( i )->GetParticle()->GetDefinition() == resi_pd ) ires = i; 
250       slow = beta;                             << 228 
251       islow = i;                               << 229       if ( slow > beta && beta != 0 ) 
252     }                                          << 230       {
253                                                << 231          slow = beta; 
254     if (fast <= beta) {                        << 232          islow = i;
255       if (fast != 1) {                         << 233       }
256         fast = beta;                           << 234 
257         ifast = i;                             << 235       if ( fast <= beta ) 
258       }                                        << 236       {
259       else {                                   << 237          if ( fast != 1 )
260         // fast is already photon then check E << 238          {
261         G4double e = ptr->Get4Momentum().e();  << 239             fast = beta; 
262         if (e > theResult.Get()->GetSecondary( << 240             ifast = i;
263           // among photons, the highest E beco << 241          } 
264           ifast = i;                           << 242          else
265         }                                      << 243          {
266       }                                        << 244             // fast is already photon then check E
267     }                                          << 245             G4double e = theResult.Get()->GetSecondary( i )->GetParticle()->Get4Momentum().e();
268   }                                            << 246             if ( e > theResult.Get()->GetSecondary( ifast )->GetParticle()->Get4Momentum().e() )   
                                                   >> 247             {
                                                   >> 248                // among photons, the highest E becomes the fastest 
                                                   >> 249                ifast = i; 
                                                   >> 250             }
                                                   >> 251          } 
                                                   >> 252       }
                                                   >> 253    }
                                                   >> 254 
                                                   >> 255    G4LorentzVector dif_4p = init_4p_lab - secs_4p_lab;
                                                   >> 256 
                                                   >> 257    G4LorentzVector p4(0);
                                                   >> 258    if ( ires == -1 ) 
                                                   >> 259    {
                                                   >> 260       // Create and Add Residual Nucleus 
                                                   >> 261       ires = nSecondaries;
                                                   >> 262       nSecondaries += 1;
269                                                   263 
270   G4LorentzVector dif_4p = init_4p_lab - secs_ << 264       G4DynamicParticle* res = new G4DynamicParticle ( resi_pd , dif_4p.v() );    
                                                   >> 265       theResult.Get()->AddSecondary ( res, secID );    
271                                                   266 
272   G4LorentzVector p4(0);                       << 267       p4 = res->Get4Momentum(); 
273   if (ires == -1) {                            << 268       if ( slow > p4.beta() ) 
274     // Create and Add Residual Nucleus         << 269       {
275     ires = nSecondaries;                       << 270          slow = p4.beta(); 
276     nSecondaries += 1;                         << 271          islow = ires;
277                                                << 272       }
278     auto res = new G4DynamicParticle(resi_pd,  << 273       dif_4p = init_4p_lab - ( secs_4p_lab + p4 );  
279     theResult.Get()->AddSecondary(res, secID); << 274    }
280                                                << 275 
281     p4 = res->Get4Momentum();                  << 276    if ( needOneMoreSec && oneMoreSec_pd)
282     if (slow > p4.beta()) {                    << 277      //
283       slow = p4.beta();                        << 278      // fca: this is not a fix, this is a crash avoidance...
284       islow = ires;                            << 279      // fca: the baryon number is still wrong, most probably because it
285     }                                          << 280      // fca: should have been decreased, but since we could not create a particle
286     dif_4p = init_4p_lab - (secs_4p_lab + p4); << 281      // fca: we just do not add it
287   }                                            << 282      //
288                                                << 283    {
289   if (needOneMoreSec && oneMoreSec_pd != nullp << 
290   //                                           << 
291   // fca: this is not a fix, this is a crash a << 
292   // fca: the baryon number is still wrong, mo << 
293   // fca: should have been decreased, but sinc << 
294   // fca: we just do not add it                << 
295   //                                           << 
296   {                                            << 
297     nSecondaries += 1;                         << 
298     auto one = new G4DynamicParticle(oneMoreSe << 
299     theResult.Get()->AddSecondary(one, secID); << 
300     p4 = one->Get4Momentum();                  << 
301     if (slow > p4.beta()) {                    << 
302       slow = p4.beta();                        << 
303       islow = nSecondaries - 1;  // Because th << 
304     }                                          << 
305     dif_4p = init_4p_lab - (secs_4p_lab + p4); << 
306   }                                            << 
307                                                << 
308   // Which is bigger dif_p or dif_e            << 
309                                                << 
310   if (dif_4p.v().mag() < std::abs(dif_4p.e())) << 
311     // Adjust p                                << 
312     if (minimum_energy < dif_4p.v().mag() && d << 
313       nSecondaries += 1;                          284       nSecondaries += 1;
314       theResult.Get()->AddSecondary(new G4Dyna << 285       G4DynamicParticle* one = new G4DynamicParticle ( oneMoreSec_pd , dif_4p.v() );    
315     }                                          << 286       theResult.Get()->AddSecondary ( one, secID );    
316   }                                            << 287       p4 = one->Get4Momentum(); 
317   else {                                       << 288       if ( slow > p4.beta() ) 
318     // dif_p > dif_e                           << 289       {
319     // at first momentum                       << 290          slow = p4.beta(); 
320     // Move residual momentum                  << 291          islow = nSecondaries-1; //Because the first is 0th, so the last becomes "nSecondaries-1"
321     p4 = theResult.Get()->GetSecondary(ires)-> << 292       }
322     theResult.Get()->GetSecondary(ires)->GetPa << 293       dif_4p = init_4p_lab - ( secs_4p_lab + p4 );  
323     dif_4p = init_4p_lab -                     << 294    }
324       (secs_4p_lab - p4 + theResult.Get()->Get << 295 
325   }                                            << 296    // Which is bigger dif_p or dif_e
326                                                << 297 
327   G4double dif_e = dif_4p.e() - (dif_4p.v()).m << 298    if ( dif_4p.v().mag() < std::abs( dif_4p.e() ) )
328                                                << 299    {
329   if (dif_e > 0) {                             << 300       // Adjust p
330     // create 2 gamma                          << 301       if ( minimum_energy < dif_4p.v().mag() && dif_4p.v().mag() < 1*MeV )
331                                                << 302       {
332     nSecondaries += 2;                         << 303 
333     G4double e1 = (dif_4p.e() - dif_4p.v().mag << 304          nSecondaries += 1;
334                                                << 305          theResult.Get()->AddSecondary ( new G4DynamicParticle ( G4Gamma::Gamma() , dif_4p.v() ), secID );
335     if (minimum_energy < e1) {                 << 306       }
336       G4ThreeVector dir = G4RandomDirection(); << 307    }
337       theResult.Get()->AddSecondary(new G4Dyna << 308    else
338       theResult.Get()->AddSecondary(new G4Dyna << 309    {
339     }                                          << 310 
340   }                                            << 311       // dif_p > dif_e 
341   else  // dif_e < 0                           << 312       // at first momentum 
342   {                                            << 313       // Move residual momentum
343     // At first reduce KE of the fastest secon << 314 
344     auto ptr = theResult.Get()->GetSecondary(i << 315       p4 = theResult.Get()->GetSecondary( ires )->GetParticle()->Get4Momentum();
345     G4double ke0 = ptr->GetKineticEnergy();    << 316       theResult.Get()->GetSecondary( ires )->GetParticle()->SetMomentum( p4.v() + dif_4p.v() ); 
346     G4ThreeVector p0 = ptr->GetMomentum();     << 317       dif_4p = init_4p_lab - ( secs_4p_lab - p4 + theResult.Get()->GetSecondary( ires )->GetParticle()->Get4Momentum()  );  
347     G4ThreeVector dir = p0.unit();             << 318    }
348                                                << 319 
349     if (ke0 + dif_e > 0) {                     << 320    G4double dif_e = dif_4p.e() - ( dif_4p.v() ).mag();
350       ptr->SetKineticEnergy(ke0 + dif_e);      << 321 
351       G4ThreeVector dp = p0 - theResult.Get()- << 322    if ( dif_e > 0 )
352       G4ThreeVector p = theResult.Get()->GetSe << 323    {
353       theResult.Get()->GetSecondary(islow)->Ge << 324 
354     }                                          << 325       // create 2 gamma 
355   }                                            << 326 
                                                   >> 327       nSecondaries += 2;
                                                   >> 328       G4double e1 = ( dif_4p.e() -dif_4p.v().mag() ) / 2;
                                                   >> 329       
                                                   >> 330       if ( minimum_energy < e1 )  
                                                   >> 331       {
                                                   >> 332          G4double costh = 2.*G4UniformRand()-1.;
                                                   >> 333          G4double phi = twopi*G4UniformRand();
                                                   >> 334          G4ThreeVector dir( std::sin(std::acos(costh))*std::cos(phi), 
                                                   >> 335                             std::sin(std::acos(costh))*std::sin(phi),
                                                   >> 336                             costh);
                                                   >> 337          theResult.Get()->AddSecondary ( new G4DynamicParticle ( G4Gamma::Gamma() , e1*dir ),  secID );    
                                                   >> 338          theResult.Get()->AddSecondary ( new G4DynamicParticle ( G4Gamma::Gamma() , -e1*dir ), secID );    
                                                   >> 339       }
                                                   >> 340    }
                                                   >> 341    else    // dif_e < 0
                                                   >> 342    {
                                                   >> 343       // At first reduce KE of the fastest secondary;
                                                   >> 344       G4double ke0 = theResult.Get()->GetSecondary( ifast )->GetParticle()->GetKineticEnergy();
                                                   >> 345       G4ThreeVector p0 = theResult.Get()->GetSecondary( ifast )->GetParticle()->GetMomentum();
                                                   >> 346       G4ThreeVector dir = ( theResult.Get()->GetSecondary( ifast )->GetParticle()->GetMomentum() ).unit();
                                                   >> 347 
                                                   >> 348       if ( ke0 + dif_e > 0 )
                                                   >> 349       {
                                                   >> 350          theResult.Get()->GetSecondary( ifast )->GetParticle()->SetKineticEnergy( ke0 + dif_e ); 
                                                   >> 351          G4ThreeVector dp = p0 - theResult.Get()->GetSecondary( ifast )->GetParticle()->GetMomentum();  
                                                   >> 352 
                                                   >> 353          G4ThreeVector p = theResult.Get()->GetSecondary( islow )->GetParticle()->GetMomentum();
                                                   >> 354          //theResult.GetSecondary( islow )->GetParticle()->SetMomentum( p - dif_e*dir ); 
                                                   >> 355          theResult.Get()->GetSecondary( islow )->GetParticle()->SetMomentum( p + dp ); 
                                                   >> 356       }
                                                   >> 357    }
356 }                                                 358 }
357                                                   359