Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/decay/src/G4Decay.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/decay/src/G4Decay.cc (Version 11.3.0) and /processes/decay/src/G4Decay.cc (Version 10.4.p3)


  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 // $Id$
 27 //                                                 28 //
 28 //                                                 29 // 
 29 // -------------------------------------------     30 // --------------------------------------------------------------
 30 //      GEANT 4 class implementation file          31 //      GEANT 4 class implementation file
 31 //                                                 32 //
 32 //      History: first implementation, based o     33 //      History: first implementation, based on object model of
 33 //      2nd December 1995, G.Cosmo                 34 //      2nd December 1995, G.Cosmo
 34 //      7 July 1996 H.Kurashige                    35 //      7 July 1996 H.Kurashige
 35 // -------------------------------------------     36 // ------------------------------------------------------------
 36 //   remove  BuildPhysicsTable()  28 Nov. 1997     37 //   remove  BuildPhysicsTable()  28 Nov. 1997  H.Kurashige
 37 //   change  DBL_EPSIRON to DBL_MIN 14 Dec. 19     38 //   change  DBL_EPSIRON to DBL_MIN 14 Dec. 1997  H.Kurashige
 38 //   modified for new ParticleChange 12 Mar. 1     39 //   modified for new ParticleChange 12 Mar. 1998  H.Kurashige
 39 //   modified for "GoodForTrackingFlag" 19 Jun     40 //   modified for "GoodForTrackingFlag" 19 June 1998  H.Kurashige
 40 //   rename thePhysicsTable to aPhyscisTable 2     41 //   rename thePhysicsTable to aPhyscisTable 2 Aug. 1998 H.Kurashige
 41 //   modified IsApplicable in order to protect     42 //   modified IsApplicable in order to protect the decay from registered 
 42 //   to resonances    12 Dec. 1998   H.Kurashi     43 //   to resonances    12 Dec. 1998   H.Kurashige 
 43 //   remove G4ParticleMomentum  6 Feb. 99 H.Ku     44 //   remove G4ParticleMomentum  6 Feb. 99 H.Kurashige
 44 //   modified  IsApplicable to activate G4Deca     45 //   modified  IsApplicable to activate G4Decay for resonances  1 Mar. 00 H.Kurashige 
 45 //   Add External Decayer         23 Feb. 2001     46 //   Add External Decayer         23 Feb. 2001  H.Kurashige
 46 //   change LowestBinValue,HighestBinValue and     47 //   change LowestBinValue,HighestBinValue and TotBin(200) 9 Feb. 2002
 47 //                                                 48 //
 48                                                    49 
 49 #include "G4Decay.hh"                              50 #include "G4Decay.hh"
 50                                                    51 
 51 #include "G4PhysicalConstants.hh"                  52 #include "G4PhysicalConstants.hh"
 52 #include "G4SystemOfUnits.hh"                      53 #include "G4SystemOfUnits.hh"
 53 #include "G4DynamicParticle.hh"                    54 #include "G4DynamicParticle.hh"
 54 #include "G4DecayProducts.hh"                      55 #include "G4DecayProducts.hh"
 55 #include "G4DecayTable.hh"                         56 #include "G4DecayTable.hh"
 56 #include "G4VDecayChannel.hh"                      57 #include "G4VDecayChannel.hh"
 57 #include "G4PhysicsLogVector.hh"                   58 #include "G4PhysicsLogVector.hh"
 58 #include "G4ParticleChangeForDecay.hh"             59 #include "G4ParticleChangeForDecay.hh"
 59 #include "G4VExtDecayer.hh"                        60 #include "G4VExtDecayer.hh"
 60                                                    61 
 61 // constructor                                     62 // constructor
 62 G4Decay::G4Decay(const G4String& processName)      63 G4Decay::G4Decay(const G4String& processName)
 63                                :G4VRestDiscret     64                                :G4VRestDiscreteProcess(processName, fDecay),
 64         verboseLevel(1),                           65         verboseLevel(1),
 65                                 HighestValue(2     66                                 HighestValue(20.0),
 66         fRemainderLifeTime(-1.0),                  67         fRemainderLifeTime(-1.0),
 67                                 pExtDecayer(nu     68                                 pExtDecayer(nullptr)
 68 {                                                  69 {
 69   // set Process Sub Type                          70   // set Process Sub Type
 70   SetProcessSubType(static_cast<int>(DECAY));      71   SetProcessSubType(static_cast<int>(DECAY));
 71                                                    72 
 72 #ifdef G4VERBOSE                                   73 #ifdef G4VERBOSE
 73   if (GetVerboseLevel()>1) {                       74   if (GetVerboseLevel()>1) {
 74     G4cout << "G4Decay  constructor " << "  Na     75     G4cout << "G4Decay  constructor " << "  Name:" << processName << G4endl;
 75   }                                                76   }
 76 #endif                                             77 #endif
 77                                                    78 
 78   pParticleChange = &fParticleChangeForDecay;      79   pParticleChange = &fParticleChangeForDecay;
 79 }                                                  80 }
 80                                                    81 
 81 G4Decay::~G4Decay()                                82 G4Decay::~G4Decay()
 82 {                                                  83 {
 83   if (pExtDecayer != nullptr) {                    84   if (pExtDecayer != nullptr) {
 84     delete pExtDecayer;                            85     delete pExtDecayer;
 85   }                                                86   }
 86 }                                                  87 }
 87                                                    88 
 88 G4bool G4Decay::IsApplicable(const G4ParticleD     89 G4bool G4Decay::IsApplicable(const G4ParticleDefinition& aParticleType)
 89 {                                                  90 {
 90    // check if the particle is stable?             91    // check if the particle is stable?
 91    if (aParticleType.GetPDGLifeTime() <0.0) {      92    if (aParticleType.GetPDGLifeTime() <0.0) {
 92      return false;                                 93      return false;
 93    } else if (aParticleType.GetPDGMass() <= 0.     94    } else if (aParticleType.GetPDGMass() <= 0.0*MeV) {
 94      return false;                                 95      return false;
 95    } else {                                        96    } else {
 96      return true;                                  97      return true; 
 97    }                                               98    }
 98 }                                                  99 }
 99                                                   100 
100 G4double G4Decay::GetMeanLifeTime(const G4Trac    101 G4double G4Decay::GetMeanLifeTime(const G4Track& aTrack  ,
101                                   G4ForceCondi    102                                   G4ForceCondition*)
102 {                                                 103 {
103    // returns the mean free path in GEANT4 int    104    // returns the mean free path in GEANT4 internal units
104    G4double meanlife;                             105    G4double meanlife;
105                                                   106 
106    // get particle                                107    // get particle 
107    const G4DynamicParticle* aParticle = aTrack    108    const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
108    const G4ParticleDefinition* aParticleDef =     109    const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
109    G4double aLife = aParticleDef->GetPDGLifeTi    110    G4double aLife = aParticleDef->GetPDGLifeTime();
110                                                   111 
111    // check if the particle is stable?            112    // check if the particle is stable?
112    if (aParticleDef->GetPDGStable()) {            113    if (aParticleDef->GetPDGStable()) {
113     //1000000 times the life time of the unive    114     //1000000 times the life time of the universe
114      meanlife = 1e24 * s;                         115      meanlife = 1e24 * s;
115                                                   116     
116    } else {                                       117    } else {
117      meanlife = aLife;                            118      meanlife = aLife;
118    }                                              119    }
119                                                   120 
120 #ifdef G4VERBOSE                                  121 #ifdef G4VERBOSE
121    if (GetVerboseLevel()>1) {                     122    if (GetVerboseLevel()>1) {
122      G4cout << "mean life time: "<< meanlife/n    123      G4cout << "mean life time: "<< meanlife/ns << "[ns]" << G4endl;
123    }                                              124    }
124 #endif                                            125 #endif
125                                                   126 
126    return  meanlife;                              127    return  meanlife;
127 }                                                 128 }
128                                                   129 
129 G4double G4Decay::GetMeanFreePath(const G4Trac    130 G4double G4Decay::GetMeanFreePath(const G4Track& aTrack,G4double, G4ForceCondition*)
130 {                                                 131 {
131    // get particle                                132    // get particle 
132    const G4DynamicParticle* aParticle = aTrack    133    const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
133    const G4ParticleDefinition* aParticleDef =     134    const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
134    G4double aMass = aParticle->GetMass();         135    G4double aMass = aParticle->GetMass();
135    G4double aLife = aParticleDef->GetPDGLifeTi    136    G4double aLife = aParticleDef->GetPDGLifeTime();
136                                                   137 
137                                                   138 
138     // returns the mean free path in GEANT4 in    139     // returns the mean free path in GEANT4 internal units
139    G4double pathlength;                           140    G4double pathlength;
140    G4double aCtau = c_light * aLife;              141    G4double aCtau = c_light * aLife;
141                                                   142 
142    // check if the particle is stable?            143    // check if the particle is stable?
143    if (aParticleDef->GetPDGStable()) {            144    if (aParticleDef->GetPDGStable()) {
144      pathlength = DBL_MAX;                        145      pathlength = DBL_MAX;
145                                                   146 
146    //check if the particle has very short life    147    //check if the particle has very short life time ?
147    } else if (aCtau < DBL_MIN) {                  148    } else if (aCtau < DBL_MIN) { 
148      pathlength =  DBL_MIN;                       149      pathlength =  DBL_MIN;
149                                                   150  
150    } else {                                       151    } else {
151     //calculate the mean free path                152     //calculate the mean free path 
152     // by using normalized kinetic energy (= E    153     // by using normalized kinetic energy (= Ekin/mass)
153      G4double   rKineticEnergy = aParticle->Ge    154      G4double   rKineticEnergy = aParticle->GetKineticEnergy()/aMass; 
154      if ( rKineticEnergy > HighestValue) {        155      if ( rKineticEnergy > HighestValue) {
155        // gamma >>  1                             156        // gamma >>  1
156        pathlength = ( rKineticEnergy + 1.0)* a    157        pathlength = ( rKineticEnergy + 1.0)* aCtau;
157      } else if ( rKineticEnergy < DBL_MIN ) {     158      } else if ( rKineticEnergy < DBL_MIN ) {
158        // too slow particle                       159        // too slow particle
159 #ifdef G4VERBOSE                                  160 #ifdef G4VERBOSE
160        if (GetVerboseLevel()>1) {                 161        if (GetVerboseLevel()>1) {
161    G4cout << "G4Decay::GetMeanFreePath()   !!p    162    G4cout << "G4Decay::GetMeanFreePath()   !!particle stops!!";
162          G4cout << aParticleDef->GetParticleNa    163          G4cout << aParticleDef->GetParticleName() << G4endl;
163    G4cout << "KineticEnergy:" << aParticle->Ge    164    G4cout << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
164        }                                          165        }
165 #endif                                            166 #endif
166        pathlength = DBL_MIN;                      167        pathlength = DBL_MIN;
167      } else {                                     168      } else {
168        // beta <1                                 169        // beta <1 
169        pathlength = (aParticle->GetTotalMoment    170        pathlength = (aParticle->GetTotalMomentum())/aMass*aCtau ;
170      }                                            171      }
171    }                                              172    }
172   return  pathlength;                             173   return  pathlength;
173 }                                                 174 }
174                                                   175 
175 void G4Decay::BuildPhysicsTable(const G4Partic    176 void G4Decay::BuildPhysicsTable(const G4ParticleDefinition&)
176 {                                                 177 {
177   return;                                         178   return;
178 }                                                 179 }
179                                                   180 
180 G4VParticleChange* G4Decay::DecayIt(const G4Tr    181 G4VParticleChange* G4Decay::DecayIt(const G4Track& aTrack, const G4Step& )
181 {                                                 182 {
182   // The DecayIt() method returns by pointer a    183   // The DecayIt() method returns by pointer a particle-change object.
183   // Units are expressed in GEANT4 internal un    184   // Units are expressed in GEANT4 internal units.
184                                                   185 
185   //   Initialize ParticleChange                  186   //   Initialize ParticleChange
186   //     all members of G4VParticleChange are     187   //     all members of G4VParticleChange are set to equal to 
187   //     corresponding member in G4Track          188   //     corresponding member in G4Track
188   fParticleChangeForDecay.Initialize(aTrack);     189   fParticleChangeForDecay.Initialize(aTrack);
189                                                   190 
190   // get particle                                 191   // get particle 
191   const G4DynamicParticle* aParticle = aTrack.    192   const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
192   const G4ParticleDefinition* aParticleDef = a    193   const G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
193                                                   194 
194   // check if  the particle is stable             195   // check if  the particle is stable
195   if (aParticleDef->GetPDGStable()) return &fP    196   if (aParticleDef->GetPDGStable()) return &fParticleChangeForDecay ;
196                                                   197  
197                                                   198 
198   //check if thePreAssignedDecayProducts exist    199   //check if thePreAssignedDecayProducts exists
199   const G4DecayProducts* o_products = (aPartic    200   const G4DecayProducts* o_products = (aParticle->GetPreAssignedDecayProducts());
200   G4bool isPreAssigned = (o_products != nullpt    201   G4bool isPreAssigned = (o_products != nullptr);   
201   G4DecayProducts* products = nullptr;            202   G4DecayProducts* products = nullptr;
202                                                   203 
203   // decay table                                  204   // decay table
204   G4DecayTable   *decaytable = aParticleDef->G    205   G4DecayTable   *decaytable = aParticleDef->GetDecayTable();
205                                                   206  
206   // check if external decayer exists             207   // check if external decayer exists
207   G4bool isExtDecayer = (decaytable == nullptr    208   G4bool isExtDecayer = (decaytable == nullptr) && (pExtDecayer != nullptr);
208                                                   209 
209   // Error due to NO Decay Table                  210   // Error due to NO Decay Table 
210   if ( (decaytable == nullptr) && !isExtDecaye    211   if ( (decaytable == nullptr) && !isExtDecayer && !isPreAssigned ){
211     if (GetVerboseLevel()>0) {                    212     if (GetVerboseLevel()>0) {
212       G4cout <<  "G4Decay::DoIt  : decay table    213       G4cout <<  "G4Decay::DoIt  : decay table not defined  for ";
213       G4cout << aParticle->GetDefinition()->Ge    214       G4cout << aParticle->GetDefinition()->GetParticleName()<< G4endl;
214     }                                             215     }
215     G4ExceptionDescription ed;                 << 
216     ed << "For " << aParticle->GetDefinition() << 
217        << " decay probability exist but decay  << 
218        << "- the particle will be killed;\n"   << 
219        << "    isExtDecayer: " << isExtDecayer << 
220        << "; isPreAssigned: " << isPreAssigned << 
221     G4Exception( "G4Decay::DecayIt ",             216     G4Exception( "G4Decay::DecayIt ",
222                  "DECAY101",JustWarning, ed);  << 217                  "DECAY101",JustWarning, 
                                                   >> 218                  "Decay table is not defined");
223                                                   219 
224     fParticleChangeForDecay.SetNumberOfSeconda    220     fParticleChangeForDecay.SetNumberOfSecondaries(0);
225     // Kill the parent particle                   221     // Kill the parent particle
226     fParticleChangeForDecay.ProposeTrackStatus    222     fParticleChangeForDecay.ProposeTrackStatus( fStopAndKill ) ;
227     fParticleChangeForDecay.ProposeLocalEnergy    223     fParticleChangeForDecay.ProposeLocalEnergyDeposit(0.0); 
228                                                   224     
229     ClearNumberOfInteractionLengthLeft();         225     ClearNumberOfInteractionLengthLeft();
230     return &fParticleChangeForDecay ;             226     return &fParticleChangeForDecay ;
231   }                                               227   }
232                                                   228 
233   if (isPreAssigned) {                            229   if (isPreAssigned) {
234     // copy decay products                        230     // copy decay products 
235     products = new G4DecayProducts(*o_products    231     products = new G4DecayProducts(*o_products); 
236   } else if ( isExtDecayer ) {                    232   } else if ( isExtDecayer ) {
237     // decay according to external decayer        233     // decay according to external decayer
238     products = pExtDecayer->ImportDecayProduct    234     products = pExtDecayer->ImportDecayProducts(aTrack);
239   } else {                                        235   } else {
240     // Decay according to decay table.            236     // Decay according to decay table.
241     // Keep trying to choose a candidate decay    237     // Keep trying to choose a candidate decay channel if the dynamic mass
242     // of the decaying particle is below the s    238     // of the decaying particle is below the sum of the PDG masses of the
243     // candidate daughter particles.              239     // candidate daughter particles.
244     // This is needed because the decay table     240     // This is needed because the decay table used in Geant4 is based on
245     // the assumption of nominal PDG masses, b    241     // the assumption of nominal PDG masses, but a wide resonance can have
246     // a dynamic masses well below its nominal    242     // a dynamic masses well below its nominal PDG masses, and therefore
247     // some of its decay channels can be below    243     // some of its decay channels can be below the kinematical threshold. 
248     // Note that, for simplicity, we ignore he    244     // Note that, for simplicity, we ignore here the possibility that
249     // one or more of the candidate daughter p    245     // one or more of the candidate daughter particles can be, in turn,
250     // wide resonance. However, if this is the    246     // wide resonance. However, if this is the case, and the channel is
251     // accepted, then the masses of the resona    247     // accepted, then the masses of the resonance daughter particles will
252     // be sampled by taking into account their    248     // be sampled by taking into account their widths.
253     G4VDecayChannel* decaychannel = nullptr;      249     G4VDecayChannel* decaychannel = nullptr;
254     G4double massParent = aParticle->GetMass()    250     G4double massParent = aParticle->GetMass();
255     decaychannel = decaytable->SelectADecayCha    251     decaychannel = decaytable->SelectADecayChannel(massParent);
256     if ( decaychannel == nullptr) {               252     if ( decaychannel == nullptr) {
257       // decay channel not found                  253       // decay channel not found
258      G4ExceptionDescription ed;                   254      G4ExceptionDescription ed;
259       ed << "Can not determine decay channel f    255       ed << "Can not determine decay channel for " 
260    << aParticleDef->GetParticleName() << G4end    256    << aParticleDef->GetParticleName() << G4endl 
261    << "  mass of dynamic particle: "              257    << "  mass of dynamic particle: " 
262    << massParent/GeV << " (GEV)" << G4endl        258    << massParent/GeV << " (GEV)" << G4endl
263    << "  dacay table has " << decaytable->entr    259    << "  dacay table has " << decaytable->entries() 
264    << " entries" << G4endl;                       260    << " entries" << G4endl;
265       G4double checkedmass=massParent;            261       G4double checkedmass=massParent;
266       if (massParent < 0.) {                      262       if (massParent < 0.) {
267   checkedmass=aParticleDef->GetPDGMass();         263   checkedmass=aParticleDef->GetPDGMass();
268   ed << "Using PDG mass ("<<checkedmass/GeV       264   ed << "Using PDG mass ("<<checkedmass/GeV 
269      << "(GeV)) in IsOKWithParentMass" << G4en    265      << "(GeV)) in IsOKWithParentMass" << G4endl; 
270       }                                           266       }
271       for (G4int ic =0;ic <decaytable->entries    267       for (G4int ic =0;ic <decaytable->entries();++ic) {
272   G4VDecayChannel * dc= decaytable->GetDecayCh    268   G4VDecayChannel * dc= decaytable->GetDecayChannel(ic);
273   ed << ic << ": BR " << dc->GetBR() << ", IsO    269   ed << ic << ": BR " << dc->GetBR() << ", IsOK? " 
274      << dc->IsOKWithParentMass(checkedmass)       270      << dc->IsOKWithParentMass(checkedmass)
275      << ", --> ";                                 271      << ", --> "; 
276   G4int ndaughters=dc->GetNumberOfDaughters();    272   G4int ndaughters=dc->GetNumberOfDaughters();
277   for (G4int id=0;id<ndaughters;++id) {           273   for (G4int id=0;id<ndaughters;++id) {
278     if (id>0) ed << " + ";   // seperator, exc    274     if (id>0) ed << " + ";   // seperator, except for first
279     ed << dc->GetDaughterName(id);                275     ed << dc->GetDaughterName(id);
280   }                                               276   }
281   ed << G4endl;                                   277   ed << G4endl;
282       }                                           278       }
283       G4Exception("G4Decay::DoIt", "DECAY003",    279       G4Exception("G4Decay::DoIt", "DECAY003", FatalException,ed);
284     } else {                                      280     } else {
285       // execute DecayIt()                        281       // execute DecayIt() 
286 #ifdef G4VERBOSE                                  282 #ifdef G4VERBOSE
287       G4int temp = decaychannel->GetVerboseLev    283       G4int temp = decaychannel->GetVerboseLevel();
288       if (GetVerboseLevel()>1) {                  284       if (GetVerboseLevel()>1) {
289   G4cout << "G4Decay::DoIt  : selected decay c    285   G4cout << "G4Decay::DoIt  : selected decay channel  addr:" 
290          << decaychannel <<G4endl;                286          << decaychannel <<G4endl;
291   decaychannel->SetVerboseLevel(GetVerboseLeve    287   decaychannel->SetVerboseLevel(GetVerboseLevel());
292       }                                           288       }
293 #endif                                            289 #endif
294       products = decaychannel->DecayIt(aPartic    290       products = decaychannel->DecayIt(aParticle->GetMass());
295 #ifdef G4VERBOSE                                  291 #ifdef G4VERBOSE
296       if (GetVerboseLevel()>1) {                  292       if (GetVerboseLevel()>1) {
297   decaychannel->SetVerboseLevel(temp);            293   decaychannel->SetVerboseLevel(temp);
298       }                                           294       }
299 #endif                                            295 #endif
300 #ifdef G4VERBOSE                                  296 #ifdef G4VERBOSE
301       if (GetVerboseLevel()>2) {                  297       if (GetVerboseLevel()>2) {
302   if (! products->IsChecked() ) products->Dump    298   if (! products->IsChecked() ) products->DumpInfo();
303       }                                           299       }
304 #endif                                            300 #endif
305     }                                             301     }
306   }                                               302   }
307                                                   303   
308   // get parent particle information .........    304   // get parent particle information ...................................
309   G4double   ParentEnergy  = aParticle->GetTot    305   G4double   ParentEnergy  = aParticle->GetTotalEnergy();
310   G4double   ParentMass    = aParticle->GetMas    306   G4double   ParentMass    = aParticle->GetMass();
311   if (ParentEnergy < ParentMass) {                307   if (ParentEnergy < ParentMass) {
312     G4ExceptionDescription ed;                 << 308     if (GetVerboseLevel()>0) {
313     ed << "Total Energy is less than its mass  << 309       G4cout << "G4Decay::DoIt  : Total Energy is less than its mass" << G4endl;
314        << "\n Particle: " << aParticle->GetDef << 310       G4cout << " Particle: " << aParticle->GetDefinition()->GetParticleName();
315        << "\n Energy:"    << ParentEnergy/MeV  << 311       G4cout << " Energy:"    << ParentEnergy/MeV << "[MeV]";
316        << "\n Mass:"      << ParentMass/MeV << << 312       G4cout << " Mass:"    << ParentMass/MeV << "[MeV]";
                                                   >> 313       G4cout << G4endl;
                                                   >> 314     }
317     G4Exception( "G4Decay::DecayIt ",             315     G4Exception( "G4Decay::DecayIt ",
318                  "DECAY102",JustWarning, ed);  << 316                  "DECAY102",JustWarning, 
                                                   >> 317                  "Total Energy is less than its mass");
319     ParentEnergy = ParentMass;                    318     ParentEnergy = ParentMass;
320   }                                               319   }
321                                                   320 
322   G4ThreeVector ParentDirection(aParticle->Get    321   G4ThreeVector ParentDirection(aParticle->GetMomentumDirection());
323                                                   322 
324   //boost all decay products to laboratory fra    323   //boost all decay products to laboratory frame
325   G4double energyDeposit = 0.0;                   324   G4double energyDeposit = 0.0;
326   G4double finalGlobalTime = aTrack.GetGlobalT    325   G4double finalGlobalTime = aTrack.GetGlobalTime();
327   G4double finalLocalTime = aTrack.GetLocalTim    326   G4double finalLocalTime = aTrack.GetLocalTime();
328   if (aTrack.GetTrackStatus() == fStopButAlive    327   if (aTrack.GetTrackStatus() == fStopButAlive ){
329     // AtRest case                                328     // AtRest case
330     finalGlobalTime += fRemainderLifeTime;        329     finalGlobalTime += fRemainderLifeTime;
331     finalLocalTime += fRemainderLifeTime;         330     finalLocalTime += fRemainderLifeTime;
332     energyDeposit += aParticle->GetKineticEner    331     energyDeposit += aParticle->GetKineticEnergy();
333     if (isPreAssigned) products->Boost( Parent    332     if (isPreAssigned) products->Boost( ParentEnergy, ParentDirection);
334   } else {                                        333   } else {
335     // PostStep case                              334     // PostStep case
336     if (!isExtDecayer) products->Boost( Parent    335     if (!isExtDecayer) products->Boost( ParentEnergy, ParentDirection);
337   }                                               336   }
338    // set polarization for daughter particles     337    // set polarization for daughter particles
339    DaughterPolarization(aTrack, products);        338    DaughterPolarization(aTrack, products);
340                                                   339 
341                                                   340 
342   //add products in fParticleChangeForDecay       341   //add products in fParticleChangeForDecay
343   G4int numberOfSecondaries = products->entrie    342   G4int numberOfSecondaries = products->entries();
344   fParticleChangeForDecay.SetNumberOfSecondari    343   fParticleChangeForDecay.SetNumberOfSecondaries(numberOfSecondaries);
345 #ifdef G4VERBOSE                                  344 #ifdef G4VERBOSE
346   if (GetVerboseLevel()>1) {                      345   if (GetVerboseLevel()>1) {
347     G4cout << "G4Decay::DoIt  : Decay vertex :    346     G4cout << "G4Decay::DoIt  : Decay vertex :";
348     G4cout << " Time: " << finalGlobalTime/ns     347     G4cout << " Time: " << finalGlobalTime/ns << "[ns]";
349     G4cout << " X:" << (aTrack.GetPosition()).    348     G4cout << " X:" << (aTrack.GetPosition()).x() /cm << "[cm]";
350     G4cout << " Y:" << (aTrack.GetPosition()).    349     G4cout << " Y:" << (aTrack.GetPosition()).y() /cm << "[cm]";
351     G4cout << " Z:" << (aTrack.GetPosition()).    350     G4cout << " Z:" << (aTrack.GetPosition()).z() /cm << "[cm]";
352     G4cout << G4endl;                             351     G4cout << G4endl;
353     G4cout << "G4Decay::DoIt  : decay products    352     G4cout << "G4Decay::DoIt  : decay products in Lab. Frame" << G4endl;
354     products->DumpInfo();                         353     products->DumpInfo();
355   }                                               354   }
356 #endif                                            355 #endif
357   G4int index;                                    356   G4int index;
358   G4ThreeVector currentPosition;                  357   G4ThreeVector currentPosition;
359   const G4TouchableHandle thand = aTrack.GetTo    358   const G4TouchableHandle thand = aTrack.GetTouchableHandle();
360   for (index=0; index < numberOfSecondaries; i    359   for (index=0; index < numberOfSecondaries; index++){
361     // get current position of the track          360     // get current position of the track
362     currentPosition = aTrack.GetPosition();       361     currentPosition = aTrack.GetPosition();
363     // create a new track object                  362     // create a new track object
364     G4Track* secondary = new G4Track( products    363     G4Track* secondary = new G4Track( products->PopProducts(),
365               finalGlobalTime ,                   364               finalGlobalTime ,
366               currentPosition );                  365               currentPosition );
367     // switch on good for tracking flag           366     // switch on good for tracking flag
368     secondary->SetGoodForTrackingFlag();          367     secondary->SetGoodForTrackingFlag();
369     secondary->SetTouchableHandle(thand);         368     secondary->SetTouchableHandle(thand);
370     // add the secondary track in the List        369     // add the secondary track in the List
371     fParticleChangeForDecay.AddSecondary(secon    370     fParticleChangeForDecay.AddSecondary(secondary);
372   }                                               371   }
373   delete products;                                372   delete products;
374                                                   373   
375   // Kill the parent particle                     374   // Kill the parent particle
376   fParticleChangeForDecay.ProposeTrackStatus(     375   fParticleChangeForDecay.ProposeTrackStatus( fStopAndKill ) ;
377   fParticleChangeForDecay.ProposeLocalEnergyDe    376   fParticleChangeForDecay.ProposeLocalEnergyDeposit(energyDeposit); 
378   fParticleChangeForDecay.ProposeLocalTime( fi    377   fParticleChangeForDecay.ProposeLocalTime( finalLocalTime );
379                                                   378   
380   // Clear NumberOfInteractionLengthLeft          379   // Clear NumberOfInteractionLengthLeft
381   ClearNumberOfInteractionLengthLeft();           380   ClearNumberOfInteractionLengthLeft();
382                                                   381   
383   return &fParticleChangeForDecay ;               382   return &fParticleChangeForDecay ;
384 }                                                 383 } 
385                                                   384 
386 void G4Decay::DaughterPolarization(const G4Tra    385 void G4Decay::DaughterPolarization(const G4Track& , G4DecayProducts* )
387 {                                                 386 {
388   // empty implementation                         387   // empty implementation
389 }                                                 388 }
390                                                   389 
391                                                   390 
392                                                   391 
393 void G4Decay::StartTracking(G4Track*)             392 void G4Decay::StartTracking(G4Track*)
394 {                                                 393 {
395   currentInteractionLength = -1.0;                394   currentInteractionLength = -1.0;
396   ResetNumberOfInteractionLengthLeft();           395   ResetNumberOfInteractionLengthLeft();
397                                                   396  
398   fRemainderLifeTime = -1.0;                      397   fRemainderLifeTime = -1.0;
399 }                                                 398 }
400                                                   399 
401 void G4Decay::EndTracking()                       400 void G4Decay::EndTracking()
402 {                                                 401 {
403   // Clear NumberOfInteractionLengthLeft          402   // Clear NumberOfInteractionLengthLeft
404   ClearNumberOfInteractionLengthLeft();           403   ClearNumberOfInteractionLengthLeft();
405                                                   404 
406   currentInteractionLength = -1.0;                405   currentInteractionLength = -1.0;
407 }                                                 406 }
408                                                   407 
409                                                   408 
410 G4double G4Decay::PostStepGetPhysicalInteracti    409 G4double G4Decay::PostStepGetPhysicalInteractionLength(
411                              const G4Track& tr    410                              const G4Track& track,
412                              G4double   previo    411                              G4double   previousStepSize,
413                              G4ForceCondition*    412                              G4ForceCondition* condition
414                             )                     413                             )
415 {                                                 414 {
416    // condition is set to "Not Forced"            415    // condition is set to "Not Forced"
417   *condition = NotForced;                         416   *condition = NotForced;
418                                                   417 
419    // pre-assigned Decay time                     418    // pre-assigned Decay time
420   G4double pTime = track.GetDynamicParticle()-    419   G4double pTime = track.GetDynamicParticle()->GetPreAssignedDecayProperTime();
421   G4double aLife = track.GetDynamicParticle()-    420   G4double aLife = track.GetDynamicParticle()->GetDefinition()->GetPDGLifeTime();
422                                                   421 
423   if (pTime < 0.) {                               422   if (pTime < 0.) {
424     // normal case                                423     // normal case 
425     if ( previousStepSize > 0.0){                 424     if ( previousStepSize > 0.0){
426       // subtract NumberOfInteractionLengthLef    425       // subtract NumberOfInteractionLengthLeft 
427       SubtractNumberOfInteractionLengthLeft(pr    426       SubtractNumberOfInteractionLengthLeft(previousStepSize);
428       if(theNumberOfInteractionLengthLeft<0.){    427       if(theNumberOfInteractionLengthLeft<0.){
429   theNumberOfInteractionLengthLeft=perMillion;    428   theNumberOfInteractionLengthLeft=perMillion;
430       }                                           429       }
431       fRemainderLifeTime = theNumberOfInteract    430       fRemainderLifeTime = theNumberOfInteractionLengthLeft*aLife;
432     }                                             431     }
433     // get mean free path                         432     // get mean free path
434     currentInteractionLength = GetMeanFreePath    433     currentInteractionLength = GetMeanFreePath(track, previousStepSize, condition);
435                                                   434     
436 #ifdef G4VERBOSE                                  435 #ifdef G4VERBOSE
437     if ((currentInteractionLength <=0.0) || (v    436     if ((currentInteractionLength <=0.0) || (verboseLevel>2)){
438       G4cout << "G4Decay::PostStepGetPhysicalI    437       G4cout << "G4Decay::PostStepGetPhysicalInteractionLength " << G4endl;
439       track.GetDynamicParticle()->DumpInfo();     438       track.GetDynamicParticle()->DumpInfo();
440       G4cout << " in Material  " << track.GetM    439       G4cout << " in Material  " << track.GetMaterial()->GetName() <<G4endl;
441       G4cout << "MeanFreePath = " << currentIn    440       G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]" <<G4endl;
442     }                                             441     }
443 #endif                                            442 #endif
444                                                   443 
445     G4double value;                               444     G4double value;
446     if (currentInteractionLength <DBL_MAX) {      445     if (currentInteractionLength <DBL_MAX) {
447       value = theNumberOfInteractionLengthLeft    446       value = theNumberOfInteractionLengthLeft * currentInteractionLength;
448       //fRemainderLifeTime = theNumberOfIntera    447       //fRemainderLifeTime = theNumberOfInteractionLengthLeft*aLife;
449     } else {                                      448     } else {
450       value = DBL_MAX;                            449       value = DBL_MAX;
451     }                                             450     }
452                                                   451 
453     return value;                                 452     return value;
454                                                   453 
455   } else {                                        454   } else {
456     //pre-assigned Decay time case                455     //pre-assigned Decay time case
457     // reminder proper time                       456     // reminder proper time
458     fRemainderLifeTime = pTime - track.GetProp    457     fRemainderLifeTime = pTime - track.GetProperTime();
459     if (fRemainderLifeTime <= 0.0) fRemainderL << 458     if (fRemainderLifeTime <= 0.0) fRemainderLifeTime = DBL_MIN;
460                                                   459     
461     G4double  rvalue=0.0;                         460     G4double  rvalue=0.0; 
462     // use pre-assigned Decay time to determin    461     // use pre-assigned Decay time to determine PIL
463     if (aLife>0.0) {                              462     if (aLife>0.0) {
464       // ordinary particle                        463       // ordinary particle
465       rvalue = (fRemainderLifeTime/aLife)*GetM    464       rvalue = (fRemainderLifeTime/aLife)*GetMeanFreePath(track, previousStepSize, condition);
466     } else {                                      465     } else {
467      // shortlived particle                       466      // shortlived particle
468       rvalue = c_light * fRemainderLifeTime;      467       rvalue = c_light * fRemainderLifeTime;
469      // by using normalized kinetic energy (=     468      // by using normalized kinetic energy (= Ekin/mass)
470      G4double   aMass =  track.GetDynamicParti    469      G4double   aMass =  track.GetDynamicParticle()->GetMass();
471      rvalue *= track.GetDynamicParticle()->Get    470      rvalue *= track.GetDynamicParticle()->GetTotalMomentum()/aMass;
472     }                                             471     }
473     return rvalue;                                472     return rvalue;
474   }                                               473   }
475 }                                                 474 }
476                                                   475 
477 G4double G4Decay::AtRestGetPhysicalInteraction    476 G4double G4Decay::AtRestGetPhysicalInteractionLength(
478                              const G4Track& tr    477                              const G4Track& track,
479                              G4ForceCondition*    478                              G4ForceCondition* condition
480                             )                     479                             )
481 {                                                 480 {
482      // condition is set to "Not Forced"          481      // condition is set to "Not Forced"
483   *condition = NotForced;                         482   *condition = NotForced;
484                                                   483 
485   G4double pTime = track.GetDynamicParticle()-    484   G4double pTime = track.GetDynamicParticle()->GetPreAssignedDecayProperTime();
486   if (pTime >= 0.) {                              485   if (pTime >= 0.) {
487     fRemainderLifeTime = pTime - track.GetProp    486     fRemainderLifeTime = pTime - track.GetProperTime();
488     if (fRemainderLifeTime <= 0.0) fRemainderL    487     if (fRemainderLifeTime <= 0.0) fRemainderLifeTime = DBL_MIN;
489   } else {                                        488   } else {
490     fRemainderLifeTime =                          489     fRemainderLifeTime = 
491       theNumberOfInteractionLengthLeft * GetMe    490       theNumberOfInteractionLengthLeft * GetMeanLifeTime(track, condition);
492   }                                               491   }
493   return fRemainderLifeTime;                      492   return fRemainderLifeTime;
494 }                                                 493 }
495                                                   494 
496                                                   495 
497 void G4Decay::SetExtDecayer(G4VExtDecayer* val    496 void G4Decay::SetExtDecayer(G4VExtDecayer* val)
498 {                                                 497 {
499   pExtDecayer = val;                              498   pExtDecayer = val;
500                                                   499 
501   // set Process Sub Type                         500   // set Process Sub Type
502   if ( pExtDecayer !=0 ) {                        501   if ( pExtDecayer !=0 ) {
503     SetProcessSubType(static_cast<int>(DECAY_E    502     SetProcessSubType(static_cast<int>(DECAY_External));
504   }                                               503   }
505 }                                                 504 }
506                                                   505 
507 G4VParticleChange* G4Decay::PostStepDoIt(         506 G4VParticleChange* G4Decay::PostStepDoIt(
508            const G4Track& aTrack,                 507            const G4Track& aTrack,
509            const G4Step&  aStep                   508            const G4Step&  aStep
510           )                                       509           )
511 {                                                 510 {
512   if ( (aTrack.GetTrackStatus() == fStopButAli    511   if ( (aTrack.GetTrackStatus() == fStopButAlive ) ||
513        (aTrack.GetTrackStatus() == fStopAndKil    512        (aTrack.GetTrackStatus() == fStopAndKill )   ){
514     fParticleChangeForDecay.Initialize(aTrack)    513     fParticleChangeForDecay.Initialize(aTrack);
515     return &fParticleChangeForDecay;              514     return &fParticleChangeForDecay;
516   } else {                                        515   } else {
517     return DecayIt(aTrack, aStep);                516     return DecayIt(aTrack, aStep);
518   }                                               517   }
519 }                                                 518 }
520                                                   519 
521 void G4Decay::ProcessDescription(std::ostream&    520 void G4Decay::ProcessDescription(std::ostream& outFile) const
522 {                                                 521 {
523   outFile << GetProcessName() << ": Decay of p    522   outFile << GetProcessName() << ": Decay of particles. \n"
524     << "kinematics of daughters are dertermine    523     << "kinematics of daughters are dertermined by DecayChannels " 
525           << " or by PreAssignedDecayProducts\    524           << " or by PreAssignedDecayProducts\n";
526 }                                                 525 }
527                                                   526