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