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