| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DsG4RadioactiveDecay.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00027 //
00028 // MODULE:              DsG4RadioactiveDecay.cc
00029 //
00030 // Author:              F Lei & P R Truscott
00031 // Organisation:        DERA UK
00032 // Customer:            ESA/ESTEC, NOORDWIJK
00033 // Contract:            12115/96/JG/NL Work Order No. 3
00034 //
00035 // Documentation avaialable at http://www.space.dera.gov.uk/space_env/rdm.html
00036 //   These include:
00037 //       User Requirement Document (URD)
00038 //       Software Specification Documents (SSD)
00039 //       Software User Manual (SUM)
00040 //       Technical Note (TN) on the physics and algorithms
00041 //
00042 //    The test and example programs are not included in the public release of 
00043 //    G4 but they can be downloaded from
00044 //      http://www.space.qinetiq.com/space_env/rdm.html
00045 // 
00046 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00047 //
00048 // CHANGE HISTORY
00049 // --------------
00050 // 16 February 2006, V.Ivanchenko fix problem in IsApplicable connected with
00051 //            8.0 particle design
00052 // 18 October 2002, F. Lei
00053 //            in the case of beta decay, added a check of the end-energy 
00054 //            to ensure it is > 0.
00055 //            ENSDF occationally have beta decay entries with zero energies
00056 //
00057 // 27 Sepetember 2001, F. Lei
00058 //            verboselevel(0) used in constructor
00059 //
00060 // 01 November 2000, F.Lei
00061 //            added " ee = e0 +1. ;" as line 763
00062 //            tagged as "radiative_decay-V02-00-02"              
00063 // 28 October 2000, F Lei 
00064 //            added fast beta decay mode. Many files have been changed.
00065 //            tagged as "radiative_decay-V02-00-01"
00066 //
00067 // 25 October 2000, F Lei, DERA UK
00068 //            1) line 1185 added 'const' to work with tag "Track-V02-00-00"
00069 //            tagged as "radiative_decay-V02-00-00"
00070 // 14 April 2000, F Lei, DERA UK
00071 // 0.b.4 release. Changes are:
00072 //            1) Use PhotonEvaporation instead of DiscreteGammaDeexcitation
00073 //            2) VR: Significant efficiency improvement
00074 // 
00075 // 29 February 2000, P R Truscott, DERA UK
00076 // 0.b.3 release.
00077 //
00078 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00080 //
00081 #include "DsG4RadioactiveDecay.hh"
00082 #include "DsG4RadioactiveDecaymessenger.hh"
00083 
00084 #include "G4DynamicParticle.hh"
00085 #include "G4DecayProducts.hh"
00086 #include "G4DecayTable.hh"
00087 #include "G4PhysicsLogVector.hh"
00088 #include "G4ParticleChangeForRadDecay.hh"
00089 #include "G4ITDecayChannel.hh"
00090 #include "G4BetaMinusDecayChannel.hh"
00091 #include "G4BetaPlusDecayChannel.hh"
00092 #include "G4KshellECDecayChannel.hh"
00093 #include "G4LshellECDecayChannel.hh"
00094 #include "G4MshellECDecayChannel.hh"
00095 #include "G4AlphaDecayChannel.hh"
00096 #include "G4VDecayChannel.hh"
00097 #include "G4RadioactiveDecayMode.hh"
00098 #include "G4Ions.hh"
00099 #include "G4IonTable.hh"
00100 #include "G4RIsotopeTable.hh"
00101 #include "G4BetaFermiFunction.hh"
00102 #include "Randomize.hh"
00103 #include "G4LogicalVolumeStore.hh"
00104 #include "G4NuclearLevelManager.hh"
00105 #include "G4NuclearLevelStore.hh"
00106 
00107 #include "G4HadTmpUtil.hh"
00108 
00109 #include <vector>
00110 #include <sstream>
00111 #include <algorithm>
00112 #include <fstream>
00113 
00114 //======================= Begin dayabay =====================
00115 #include <CLHEP/Random/RandExponential.h>
00116 #include "Li9He8Decay.hh"
00117 //======================= End dayabay   =====================
00118 using namespace CLHEP;
00119 
00120 const G4double   DsG4RadioactiveDecay::levelTolerance =2.0*keV;
00121 
00123 //
00124 //
00125 // Constructor
00126 //
00127 DsG4RadioactiveDecay::DsG4RadioactiveDecay
00128   (const G4String& processName)
00129   :G4VRestDiscreteProcess(processName, fDecay), HighestBinValue(10.0),
00130    LowestBinValue(1.0e-3), TotBin(200), verboseLevel(0)
00131 {
00132   G4cout << "Using dyw Radioactivie Decay!!! " << G4endl;
00133 #ifdef G4VERBOSE
00134   if (GetVerboseLevel()>1) {
00135     G4cout <<"DsG4RadioactiveDecay constructor    Name: ";
00136     G4cout <<processName << G4endl;   }
00137 #endif
00138 
00139   theRadioactiveDecaymessenger = new DsG4RadioactiveDecaymessenger(this);
00140   theIsotopeTable              = new G4RIsotopeTable();
00141   aPhysicsTable                = 0;
00142   pParticleChange              = &fParticleChangeForRadDecay;
00143   
00144   //
00145   // Now register the Isotopetable with G4IonTable.
00146   //
00147   G4IonTable *theIonTable =
00148     (G4IonTable *)(G4ParticleTable::GetParticleTable()->GetIonTable());
00149   G4VIsotopeTable *aVirtualTable = theIsotopeTable;
00150   theIonTable->RegisterIsotopeTable(aVirtualTable);
00151   //
00152   //
00153   // Reset the contents of the list of nuclei for which decay scheme data
00154   // have been loaded.
00155   //
00156   LoadedNuclei.clear();
00157   //
00158   //
00159   // Apply default values.
00160   //
00161   NSourceBin  = 1;
00162   SBin[0]     = 0.* s;
00163   SBin[1]     = 1e10 * s;
00164   SProfile[0] = 1.;
00165   SProfile[1] = 1.;
00166   NDecayBin   = 1;
00167   DBin[0]     = 9.9e9 * s ;
00168   DBin[1]     = 1e10 * s;
00169   DProfile[0] = 1.;
00170   DProfile[1] = 0.;
00171   NSplit      = 1;
00172   AnalogueMC  = true ;
00173   FBeta       = false ;
00174   BRBias      = true ;
00175 
00176 //========= Begin dayabay ========
00177   m_Li9He8 = new Li9He8Decay();
00178   m_completedecay = true;
00179 //========= End dayabay ========
00180 
00181   //
00182   // RDM applies to xall logical volumes as default
00183   SelectAllVolumes();
00184 }
00186 //
00187 //
00188 // Destructor
00189 //
00190 DsG4RadioactiveDecay::~DsG4RadioactiveDecay()
00191 {
00192   if (aPhysicsTable != 0)
00193     {
00194       aPhysicsTable->clearAndDestroy();
00195       delete aPhysicsTable;
00196     }
00197 
00198 //========= Begin dayabay ========
00199   if(m_Li9He8) delete m_Li9He8;
00200 //========= End dayabay ========
00201 
00202   //  delete theIsotopeTable;
00203   delete theRadioactiveDecaymessenger;
00204 }
00205 
00207 //
00208 //
00209 // IsApplicable
00210 //
00211 G4bool DsG4RadioactiveDecay::IsApplicable( const G4ParticleDefinition &
00212   aParticle)
00213 {
00214   //
00215   //
00216   // All particles, other than G4Ions, are rejected by default.
00217   //
00218   if (aParticle.GetParticleName() == "GenericIon")      {return true;}
00219   else if (!(aParticle.GetParticleType() == "nucleus") || aParticle.GetPDGLifeTime() < 0. ) {return false;}
00220 
00221   //
00222   //
00223   // Determine whether the nuclide falls into the correct A and Z range.
00224   //
00225   G4int A = ((const G4Ions*) (&aParticle))->GetAtomicMass();
00226   G4int Z = ((const G4Ions*) (&aParticle))->GetAtomicNumber();
00227   if( A> theNucleusLimits.GetAMax() || A< theNucleusLimits.GetAMin())
00228     {return false;}
00229   else if( Z> theNucleusLimits.GetZMax() || Z< theNucleusLimits.GetZMin())
00230     {return false;}
00231   return true;
00232 }
00234 //
00235 //
00236 // IsLoaded
00237 //
00238 G4bool DsG4RadioactiveDecay::IsLoaded(const G4ParticleDefinition &
00239   aParticle)
00240 {
00241   //
00242   //
00243   // Check whether the radioactive decay data on the ion have already been
00244   // loaded.
00245   //
00246   return std::binary_search(LoadedNuclei.begin(),
00247                        LoadedNuclei.end(),
00248                        aParticle.GetParticleName());
00249 }
00251 //
00252 //
00253 // SelectAVolume
00254 //
00255 void DsG4RadioactiveDecay::SelectAVolume(const G4String aVolume)
00256 {
00257   
00258   G4LogicalVolumeStore *theLogicalVolumes;
00259   G4LogicalVolume *volume;
00260   theLogicalVolumes=G4LogicalVolumeStore::GetInstance();
00261   for (size_t i = 0; i < theLogicalVolumes->size(); i++){
00262     volume=(*theLogicalVolumes)[i];
00263     if (volume->GetName() == aVolume) {
00264       ValidVolumes.push_back(aVolume);
00265       std::sort(ValidVolumes.begin(), ValidVolumes.end());
00266       // sort need for performing binary_search
00267 #ifdef G4VERBOSE
00268       if (GetVerboseLevel()>0)
00269         G4cout << " RDM Applies to : " << aVolume << G4endl; 
00270 #endif
00271     }else if(i ==  theLogicalVolumes->size())
00272       {
00273         G4cerr << "SelectAVolume: "<<aVolume << " is not a valid logical volume name"<< G4endl; 
00274       }
00275   }
00276 }
00278 //
00279 //
00280 // DeSelectAVolume
00281 //
00282 void DsG4RadioactiveDecay::DeselectAVolume(const G4String aVolume)
00283 {
00284   G4LogicalVolumeStore *theLogicalVolumes;
00285   G4LogicalVolume *volume;
00286   theLogicalVolumes=G4LogicalVolumeStore::GetInstance();
00287   for (size_t i = 0; i < theLogicalVolumes->size(); i++){
00288     volume=(*theLogicalVolumes)[i];
00289     if (volume->GetName() == aVolume) {
00290       std::vector<G4String>::iterator location;
00291       location = std::find(ValidVolumes.begin(),ValidVolumes.end(),aVolume);
00292       if (location != ValidVolumes.end()) {
00293         ValidVolumes.erase(location);
00294         std::sort(ValidVolumes.begin(), ValidVolumes.end());
00295       }else{
00296         G4cerr << " DeselectVolume:" << aVolume << " is not in the list"<< G4endl; 
00297       }   
00298 #ifdef G4VERBOSE
00299       if (GetVerboseLevel()>0)
00300         G4cout << " DeselectVolume: " << aVolume << " is removed from list"<<G4endl; 
00301 #endif
00302     }else if(i ==  theLogicalVolumes->size())
00303       {
00304         G4cerr << " DeselectVolume:" << aVolume << "is not a valid logical volume name"<< G4endl; 
00305       }
00306   }
00307 }
00309 //
00310 //
00311 // SelectAllVolumes
00312 //
00313 void DsG4RadioactiveDecay::SelectAllVolumes() 
00314 {
00315   G4LogicalVolumeStore *theLogicalVolumes;
00316   G4LogicalVolume *volume;
00317   theLogicalVolumes=G4LogicalVolumeStore::GetInstance();
00318   ValidVolumes.clear();
00319 #ifdef G4VERBOSE
00320   if (GetVerboseLevel()>0)
00321     G4cout << " RDM Applies to all Volumes"  << G4endl;
00322 #endif
00323   for (size_t i = 0; i < theLogicalVolumes->size(); i++){
00324     volume=(*theLogicalVolumes)[i];
00325     ValidVolumes.push_back(volume->GetName());    
00326 #ifdef G4VERBOSE
00327     if (GetVerboseLevel()>0)
00328       G4cout << "         RDM Applies to Volume "  << volume->GetName() << G4endl;
00329 #endif
00330   }
00331   std::sort(ValidVolumes.begin(), ValidVolumes.end());
00332   // sort needed in order to allow binary_search
00333 }
00335 //
00336 //
00337 // DeSelectAllVolumes
00338 //
00339 void DsG4RadioactiveDecay::DeselectAllVolumes() 
00340 {
00341   ValidVolumes.clear();
00342 #ifdef G4VERBOSE
00343   if (GetVerboseLevel()>0)
00344     G4cout << " RDM removed from all volumes" << G4endl; 
00345 #endif
00346   
00347 }
00348 
00350 //
00351 //
00352 // IsRateTableReady
00353 //
00354 G4bool DsG4RadioactiveDecay::IsRateTableReady(const G4ParticleDefinition &
00355   aParticle)
00356 {
00357   //
00358   //
00359   // Check whether the radioactive decay rates table on the ion has already
00360   // been calculated.
00361   //
00362   G4String aParticleName = aParticle.GetParticleName();
00363   for (size_t i = 0; i < theDecayRateTableVector.size(); i++)
00364     {
00365       if (theDecayRateTableVector[i].GetIonName() == aParticleName)
00366         return true ;
00367     }
00368   return false;
00369 }
00371 //
00372 //
00373 // GetDecayRateTable
00374 //
00375 // retrieve the decayratetable for the specified aParticle
00376 //
00377 void DsG4RadioactiveDecay::GetDecayRateTable(const G4ParticleDefinition &
00378   aParticle)
00379 {
00380 
00381   G4String aParticleName = aParticle.GetParticleName();
00382 
00383   for (size_t i = 0; i < theDecayRateTableVector.size(); i++)
00384     {
00385       if (theDecayRateTableVector[i].GetIonName() == aParticleName)
00386         {
00387           theDecayRateVector = theDecayRateTableVector[i].GetItsRates() ;
00388         }
00389     }
00390 #ifdef G4VERBOSE
00391         if (GetVerboseLevel()>0)
00392           {
00393             G4cout <<"The DecayRate Table for "
00394                    << aParticleName << " is selected." <<  G4endl;
00395           }
00396 #endif
00397 }
00399 //
00400 //
00401 // GetTaoTime
00402 //
00403 // to perform the convilution of the sourcetimeprofile function with the 
00404 // decay constants in the decay chain. 
00405 //
00406 G4double DsG4RadioactiveDecay::GetTaoTime(G4double t, G4double tao)
00407 {
00408   G4double taotime =0.;
00409   G4int nbin;
00410   if ( t > SBin[NSourceBin]) {
00411     nbin  = NSourceBin;}
00412   else {
00413     nbin = 0;
00414     while (t > SBin[nbin]) nbin++;
00415     nbin--;}
00416   if (nbin > 0) { 
00417     for (G4int i = 0; i < nbin; i++) 
00418       {
00419         taotime += SProfile[i] * (std::exp(-(t-SBin[i+1])/tao)-std::exp(-(t-SBin[i])/tao));
00420       }
00421   }
00422   taotime +=  SProfile[nbin] * (1-std::exp(-(t-SBin[nbin])/tao));
00423 #ifdef G4VERBOSE
00424   if (GetVerboseLevel()>1)
00425     {G4cout <<" Tao time: " <<taotime <<G4endl;}
00426 #endif
00427   return  taotime ;
00428 }
00429  
00431 //
00432 //
00433 // GetDecayTime
00434 //
00435 // Randomly select a decay time for the decay process, following the supplied
00436 // decay time bias scheme.
00437 //
00438 G4double DsG4RadioactiveDecay::GetDecayTime()
00439 {
00440   G4double decaytime = 0.;
00441   G4double rand = G4UniformRand();
00442   G4int i = 0;
00443   while ( DProfile[i] < rand) i++;
00444   rand = G4UniformRand();
00445   decaytime = DBin[i] + rand*(DBin[i+1]-DBin[i]);
00446 #ifdef G4VERBOSE
00447   if (GetVerboseLevel()>1)
00448     {G4cout <<" Decay time: " <<decaytime <<"[ns]" <<G4endl;}
00449 #endif
00450   return  decaytime;        
00451 }
00452 
00454 //
00455 //
00456 // GetDecayTimeBin
00457 //
00458 //
00459 //
00460 G4int DsG4RadioactiveDecay::GetDecayTimeBin(const G4double aDecayTime)
00461 {
00462   for (G4int i = 0; i < NDecayBin; i++) 
00463     {
00464       if ( aDecayTime > DBin[i]) return i+1;      
00465     }
00466   return  1;
00467 }
00469 //
00470 //
00471 // GetMeanLifeTime
00472 //
00473 // this is required by the base class 
00474 //
00475 G4double DsG4RadioactiveDecay::GetMeanLifeTime(const G4Track& theTrack,
00476                                              G4ForceCondition* )
00477 {
00478   // For varience reduction implementation the time is set to 0 so as to 
00479   // force the particle to decay immediately.
00480   // in analogueMC mode it return the particles meanlife.
00481   // 
00482   G4double meanlife = 0.;
00483   if (AnalogueMC) {
00484     const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
00485     G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
00486     G4double theLife = theParticleDef->GetPDGLifeTime();
00487       
00488 #ifdef G4VERBOSE
00489     if (GetVerboseLevel()>2)
00490       {
00491         G4cout <<"DsG4RadioactiveDecay::GetMeanLifeTime() " <<G4endl;
00492         G4cout <<"KineticEnergy:" <<theParticle->GetKineticEnergy()/GeV <<"[GeV]";
00493         G4cout <<"Mass:" <<theParticle->GetMass()/GeV <<"[GeV]"; 
00494         G4cout <<"Life time: " <<theLife/ns <<"[ns]" << G4endl;
00495       }
00496 #endif
00497     if (theParticleDef->GetPDGStable()) {meanlife = DBL_MAX;}
00498     else if (theLife < 0.0) {meanlife = DBL_MAX;}
00499     else {meanlife = theLife;}
00500   }
00501 #ifdef G4VERBOSE
00502   if (GetVerboseLevel()>1)
00503     {G4cout <<"mean life time: " <<meanlife <<"[ns]" <<G4endl;}
00504 #endif
00505   
00506   return  meanlife;
00507 }
00509 //
00510 //
00511 // GetMeanFreePath
00512 //
00513 // it is of similar functions to GetMeanFreeTime 
00514 //
00515 G4double DsG4RadioactiveDecay::GetMeanFreePath (const G4Track& aTrack,
00516                                               G4double, G4ForceCondition*)
00517 {
00518   // constants
00519   G4bool isOutRange ;
00520   
00521   // get particle
00522   const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
00523   
00524   // returns the mean free path in GEANT4 internal units
00525   G4double pathlength;
00526   G4ParticleDefinition* aParticleDef = aParticle->GetDefinition();
00527   G4double aCtau = c_light * aParticleDef->GetPDGLifeTime();
00528   G4double aMass = aParticle->GetMass();
00529   
00530 #ifdef G4VERBOSE
00531   if (GetVerboseLevel()>2) {
00532     G4cout << "DsG4RadioactiveDecay::GetMeanFreePath() "<< G4endl;
00533     G4cout << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
00534     G4cout << "Mass:" << aMass/GeV <<"[GeV]";
00535     G4cout << "c*Tau:" << aCtau/m <<"[m]" <<G4endl;
00536   }
00537 #endif
00538   
00539   // check if the particle is stable?
00540   if (aParticleDef->GetPDGStable()) {
00541     pathlength = DBL_MAX;
00542     
00543   } else if (aCtau < 0.0) {
00544     pathlength =  DBL_MAX;
00545     
00546     //check if the particle has very short life time ?
00547   } else if (aCtau < DBL_MIN) {
00548     pathlength =  DBL_MIN;
00549     
00550     //check if zero mass
00551   } else if (aMass <  DBL_MIN)  {
00552     pathlength =  DBL_MAX;
00553 #ifdef G4VERBOSE
00554     if (GetVerboseLevel()>1) {
00555       G4cerr << " Zero Mass particle " << G4endl;
00556     }
00557 #endif
00558    } else {
00559      //calculate the mean free path
00560      // by using normalized kinetic energy (= Ekin/mass)
00561      G4double   rKineticEnergy = aParticle->GetKineticEnergy()/aMass;
00562      if ( rKineticEnergy > HighestBinValue) {
00563        // beta >> 1
00564        pathlength = ( rKineticEnergy + 1.0)* aCtau;
00565      } else if ( rKineticEnergy > LowestBinValue) {
00566        // check if aPhysicsTable exists
00567        if (aPhysicsTable == 0) BuildPhysicsTable(*aParticleDef);
00568        // beta is in the range valid for PhysicsTable
00569        pathlength = aCtau *
00570          ((*aPhysicsTable)(0))-> GetValue(rKineticEnergy,isOutRange);
00571      } else if ( rKineticEnergy < DBL_MIN ) {
00572        // too slow particle
00573 #ifdef G4VERBOSE
00574        if (GetVerboseLevel()>2) {
00575          G4cout << "G4Decay::GetMeanFreePath()   !!particle stops!!";
00576          G4cout << aParticleDef->GetParticleName() << G4endl;
00577          G4cout << "KineticEnergy:" << aParticle->GetKineticEnergy()/GeV <<"[GeV]";
00578        }
00579 #endif
00580        pathlength = DBL_MIN;
00581      } else {
00582        // beta << 1
00583        pathlength = (aParticle->GetTotalMomentum())/aMass*aCtau ;
00584      }
00585    }
00586 #ifdef G4VERBOSE
00587    if (GetVerboseLevel()>1) {
00588      G4cout << "mean free path: "<< pathlength/m << "[m]" << G4endl;
00589    }
00590 #endif
00591    return  pathlength;
00592 }
00594 //
00595 //
00596 //
00597 //
00598 void DsG4RadioactiveDecay::BuildPhysicsTable(const G4ParticleDefinition&)
00599 {
00600   // if aPhysicsTableis has already been created, do nothing
00601   if (aPhysicsTable != 0) return;
00602 
00603   // create  aPhysicsTable
00604   if (GetVerboseLevel()>1) G4cerr <<" G4Decay::BuildPhysicsTable() "<< G4endl;
00605   aPhysicsTable = new G4PhysicsTable(1);
00606 
00607   //create physics vector
00608   G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
00609                                                        LowestBinValue,
00610                                                        HighestBinValue,
00611                                                        TotBin);
00612 
00613   G4double beta, gammainv;
00614   // fill physics Vector
00615   G4int i;
00616   for ( i = 0 ; i < TotBin ; i++ ) {
00617       gammainv = 1.0/(aVector->GetLowEdgeEnergy(i) + 1.0);
00618       beta  = std::sqrt((1.0 - gammainv)*(1.0 +gammainv));
00619       aVector->PutValue(i, beta/gammainv);
00620   }
00621   aPhysicsTable->insert(aVector);
00622 }
00624 //
00625 // LoadDecayTable
00626 // 
00627 //     To load the decay scheme from the Radioactivity database for 
00628 //     theParentNucleus.
00629 //
00630 G4DecayTable *DsG4RadioactiveDecay::LoadDecayTable (G4ParticleDefinition
00631   &theParentNucleus)
00632 {
00633   //
00634   //
00635   // Create and initialise variables used in the method.
00636   //
00637   G4DecayTable *theDecayTable = new G4DecayTable();
00638   //
00639   //
00640   // Determine the filename of the file containing radioactive decay data.  Open
00641   // it.
00642   //
00643   G4int A    = ((const G4Ions*)(&theParentNucleus))->GetAtomicMass();
00644   G4int Z    = ((const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
00645   G4double E = ((const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
00646 
00647   if ( !getenv("G4RADIOACTIVEDATA") ) {
00648     G4cout << "Please setenv G4RADIOACTIVEDATA to point to the radioactive decay data files." << G4endl;
00649     throw G4HadronicException(__FILE__, __LINE__, 
00650               "Please setenv G4RADIOACTIVEDATA to point to the radioactive decay data files.");
00651   }
00652   G4String dirName = getenv("G4RADIOACTIVEDATA");
00653   LoadedNuclei.push_back(theParentNucleus.GetParticleName());
00654   std::sort( LoadedNuclei.begin(), LoadedNuclei.end() );
00655   // sort needed to allow binary_search
00656 
00657   std::ostringstream os;
00658   os <<dirName <<"/z" <<Z <<".a" <<A <<'\0';
00659   G4String file = os.str();
00660 
00661   
00662   std::ifstream DecaySchemeFile(file);
00663 
00664   if (!DecaySchemeFile)
00665     //
00666     //
00667     // There is no radioactive decay data for this nucleus.  Return a null
00668     // decay table.
00669     //
00670     {
00671       G4cerr <<"G4RadoactiveDecay::LoadDecayTable() : cannot find ion radioactive decay file " <<G4endl;
00672       theDecayTable = 0;
00673       return theDecayTable;
00674     }
00675   //
00676   //
00677   // Initialise variables used for reading in radioactive decay data.
00678   //
00679   G4int    nMode = 7;
00680   G4bool   modeFirstRecord[7];
00681   G4double modeTotalBR[7];
00682   G4double modeSumBR[7];
00683   G4int i;
00684   for (i=0; i<nMode; i++)
00685     {
00686       modeFirstRecord[i] = true;
00687       modeSumBR[i]       = 0.0;
00688     }
00689 
00690   G4bool complete(false);
00691   G4bool found(false);
00692   char inputChars[80]={' '};
00693   G4String inputLine;
00694   G4String recordType("");
00695   G4RadioactiveDecayMode theDecayMode;
00696   G4double a(0.0);
00697   G4double b(0.0);
00698   G4double c(0.0);
00699   G4double n(1.0);
00700   G4double e0;
00701   //
00702   //
00703   // Go through each record in the data file until you identify the decay
00704   // data relating to the nuclide of concern.
00705   //
00706 //  while (!complete && -DecaySchemeFile.getline(inputChars, 80).eof() != EOF)
00707   while (!complete && !DecaySchemeFile.getline(inputChars, 80).eof())    {
00708       inputLine = inputChars;
00709       //    G4String::stripType stripend(1);
00710       //    inputLine = inputLine.strip(stripend);
00711       inputLine = inputLine.strip(1);
00712       if (inputChars[0] != '#' && inputLine.length() != 0)
00713         {
00714           std::istringstream tmpStream(inputLine);
00715           if (inputChars[0] == 'P')
00716             //
00717             //
00718             // Nucleus is a parent type.  Check the excitation level to see if it matches
00719             // that of theParentNucleus
00720             //
00721             {
00722               tmpStream >>recordType >>a >>b;
00723               if (found) {complete = true;}
00724               else {found = (std::abs(a*keV - E)<levelTolerance);}
00725             }
00726           else if (found)
00727             {
00728               //
00729               //
00730               // The right part of the radioactive decay data file has been found.  Search
00731               // through it to determine the mode of decay of the subsequent records.
00732               //
00733               if (inputChars[0] == 'W') {
00734 #ifdef G4VERBOSE
00735                 if (GetVerboseLevel()>0) {
00736                   // a comment line identified and print out the message
00737                   //
00738                   G4cout << " Warning in DsG4RadioactiveDecay::LoadDecayTable " << G4endl;
00739                   G4cout << "   In data file " << file << G4endl;
00740                   G4cout << "   " << inputLine << G4endl;
00741                 }
00742 #endif
00743               } 
00744               else 
00745                 {
00746                   tmpStream >>theDecayMode >>a >>b >>c;
00747                   a/=1000.;
00748                   c/=1000.;
00749           
00750                   //    cout<< "The decay mode is [LoadTable] "<<theDecayMode<<G4endl;
00751           
00752                   switch (theDecayMode)
00753                     {
00754                     case IT:
00755                       //
00756                       //
00757                       // Decay mode is isomeric transition.
00758                       //
00759                       {
00760                         G4ITDecayChannel *anITChannel = new G4ITDecayChannel
00761                           (GetVerboseLevel(), (const G4Ions*) &theParentNucleus, b);
00762                         theDecayTable->Insert(anITChannel);
00763                         break;
00764                       }
00765                     case BetaMinus:
00766                       //
00767                       //
00768                       // Decay mode is beta-.
00769                       //
00770                       if (modeFirstRecord[1])
00771                         {modeFirstRecord[1] = false; modeTotalBR[1] = b;}
00772                       else
00773                         {
00774                           if (c > 0.) {
00775                             // to work out the Fermi function normalization factor first
00776                             G4BetaFermiFunction* aBetaFermiFunction = new G4BetaFermiFunction (A, (Z+1));
00777                             e0 = c*MeV/0.511;
00778                             n = aBetaFermiFunction->GetFFN(e0);
00779                             
00780                             // now to work out the histogram and initialise the random generator
00781                             G4int npti = 100;                           
00782                             G4double* pdf = new G4double[npti];
00783                             G4int ptn;
00784                             G4double g,e,ee,f;
00785                             ee = e0+1.;
00786                             for (ptn=0; ptn<npti; ptn++) {
00787                               // e =e0*(ptn+1.)/102.;
00788                               // bug fix (#662) (flei, 22/09/2004)
00789                               e =e0*(ptn+0.5)/100.;
00790                               g = e+1.;
00791                               f = std::sqrt(g*g-1)*(ee-g)*(ee-g)*g;
00792                               pdf[ptn] = f*aBetaFermiFunction->GetFF(e);
00793                             }             
00794                             RandGeneral* aRandomEnergy = new RandGeneral( pdf, npti);  
00795                             G4BetaMinusDecayChannel *aBetaMinusChannel = new
00796                               G4BetaMinusDecayChannel (GetVerboseLevel(), &theParentNucleus,
00797                                                        b, c*MeV, a*MeV, n, FBeta, aRandomEnergy);
00798                             theDecayTable->Insert(aBetaMinusChannel);
00799                             modeSumBR[1] += b;
00800                             delete[] pdf;
00801                             delete aBetaFermiFunction;
00802                           }
00803                         }
00804                       break;
00805                     case BetaPlus:
00806                       //
00807                       //
00808                       // Decay mode is beta+.
00809                       //
00810                       if (modeFirstRecord[2])
00811                         {modeFirstRecord[2] = false; modeTotalBR[2] = b;}
00812                       else
00813                         {
00814                           //  e0 = c*MeV/0.511;
00815                           // bug fix (#662) (flei, 22/09/2004)
00816                           // need to test e0 as there are some data files (e.g. z67.a162) which have entries for beta+
00817                           // with Q < 2Me
00818                           //
00819                           e0 = c*MeV/0.511 -2.;
00820                           if (e0 > 0.) {
00821                             G4BetaFermiFunction* aBetaFermiFunction = new G4BetaFermiFunction (A, -(Z-1));
00822                             
00823                             n = aBetaFermiFunction->GetFFN(e0);
00824 
00825                             // now to work out the histogram and initialise the random generator
00826                             G4int npti = 100;                           
00827                             G4double* pdf = new G4double[npti];
00828                             G4int ptn;
00829                             G4double g,e,ee,f;
00830                             ee = e0+1.;
00831                             for (ptn=0; ptn<npti; ptn++) {
00832                               // e =e0*(ptn+1.)/102.;
00833                               // bug fix (#662) (flei, 22/09/2004)
00834                               e =e0*(ptn+0.5)/100.;
00835                               g = e+1.;
00836                               f = std::sqrt(g*g-1)*(ee-g)*(ee-g)*g;
00837                               pdf[ptn] = f*aBetaFermiFunction->GetFF(e);
00838                             }
00839                             RandGeneral* aRandomEnergy = new RandGeneral( pdf, npti);  
00840                             G4BetaPlusDecayChannel *aBetaPlusChannel = new 
00841                               G4BetaPlusDecayChannel (GetVerboseLevel(), &theParentNucleus,
00842                                                       b, c*MeV, a*MeV, n, FBeta, aRandomEnergy);
00843                             theDecayTable->Insert(aBetaPlusChannel);
00844                             modeSumBR[2] += b;
00845                             
00846                             delete[] pdf;
00847                             delete aBetaFermiFunction;        
00848                           }
00849                         }
00850                       break;
00851                     case KshellEC:
00852                       //
00853                       //
00854                       // Decay mode is K-electron capture.
00855                       //
00856                       if (modeFirstRecord[3])
00857                         {modeFirstRecord[3] = false; modeTotalBR[3] = b;}
00858                       else
00859                         {
00860                           G4KshellECDecayChannel *aKECChannel = new
00861                             G4KshellECDecayChannel (GetVerboseLevel(), &theParentNucleus,
00862                                                     b, c*MeV, a*MeV);
00863                           theDecayTable->Insert(aKECChannel);
00864                           //delete aKECChannel;
00865                           modeSumBR[3] += b;
00866                         }
00867                       break;
00868                     case LshellEC:
00869                       //
00870                       //
00871                       // Decay mode is L-electron capture.
00872                       //
00873                       if (modeFirstRecord[4])
00874                         {modeFirstRecord[4] = false; modeTotalBR[4] = b;}
00875                       else
00876                         {
00877                           G4LshellECDecayChannel *aLECChannel = new
00878                             G4LshellECDecayChannel (GetVerboseLevel(), &theParentNucleus,
00879                                                     b, c*MeV, a*MeV);
00880                           theDecayTable->Insert(aLECChannel);
00881                           //delete aLECChannel;
00882                           modeSumBR[4] += b;
00883                         }
00884                       break;
00885                     case MshellEC:
00886                       //
00887                       //
00888                       // Decay mode is M-electron capture. In this implementation it is added to L-shell case
00889                       //
00890                       if (modeFirstRecord[5])
00891                         {modeFirstRecord[5] = false; modeTotalBR[5] = b;}
00892                       else
00893                         {
00894                           G4MshellECDecayChannel *aMECChannel = new
00895                             G4MshellECDecayChannel (GetVerboseLevel(), &theParentNucleus,
00896                                                     b, c*MeV, a*MeV);
00897                           theDecayTable->Insert(aMECChannel);
00898                           modeSumBR[5] += b;
00899                         }
00900                       break;
00901                     case Alpha:
00902                       //
00903                       //
00904                       // Decay mode is alpha.
00905                       //
00906                       if (modeFirstRecord[6])
00907                         {modeFirstRecord[6] = false; modeTotalBR[6] = b;}
00908                       else
00909                         {
00910                           G4AlphaDecayChannel *anAlphaChannel = new
00911                             G4AlphaDecayChannel (GetVerboseLevel(), &theParentNucleus,
00912                                                  b, c*MeV, a*MeV);
00913                           theDecayTable->Insert(anAlphaChannel);
00914                           //          delete anAlphaChannel;
00915                           modeSumBR[6] += b;
00916                         }
00917                       break;
00918                     case ERROR:
00919                     default:
00920                       // 
00921                       // 
00922                       G4cout << " There is an  error in decay mode selection! exit RDM now" << G4endl;
00923                       exit(0);
00924                       
00925                     }
00926                 }
00927             }
00928         }
00929 
00930     }  
00931   DecaySchemeFile.close();
00932   if (!found && E > 0.) {
00933     // cases where IT cascade follows immediately after a decay
00934     
00935     // Decay mode is isomeric transition.
00936     //
00937     G4ITDecayChannel *anITChannel = new G4ITDecayChannel
00938       (GetVerboseLevel(), (const G4Ions*) &theParentNucleus, 1);
00939     theDecayTable->Insert(anITChannel);
00940   }
00941   //
00942   //
00943   // Go through the decay table and make sure that the branching ratios are
00944   // correctly normalised.
00945   //
00946   G4VDecayChannel       *theChannel             = 0;
00947   G4NuclearDecayChannel *theNuclearDecayChannel = 0;
00948   G4String mode                     = "";
00949   G4int j                           = 0;
00950   G4double theBR                    = 0.0;
00951   for (i=0; i<theDecayTable->entries(); i++)
00952     {
00953       theChannel             = theDecayTable->GetDecayChannel(i);
00954       theNuclearDecayChannel = static_cast<G4NuclearDecayChannel *>(theChannel);
00955       theDecayMode           = theNuclearDecayChannel->GetDecayMode();
00956       j          = 0;
00957       if (theDecayMode != IT)
00958         {
00959           theBR = theChannel->GetBR();
00960           theChannel->SetBR(theBR*modeTotalBR[theDecayMode]/modeSumBR[theDecayMode]);
00961         }
00962     }  
00963 
00964   if (theDecayTable && GetVerboseLevel()>1)
00965     {
00966       G4cout <<"DsG4RadioactiveDecay::LoadDecayTable()" << G4endl;
00967       G4cout << "  No. of  entries: "<< theDecayTable->entries() <<G4endl;
00968       theDecayTable ->DumpInfo();
00969     }
00970 
00971   return theDecayTable;
00972 }
00973 
00975 //
00976 //
00977 void DsG4RadioactiveDecay::SetDecayRate(G4int theZ, G4int theA, G4double theE, 
00978                                        G4int theG, std::vector<G4double> theRates, 
00979                                        std::vector<G4double> theTaos)
00980 { 
00981   //fill the decay rate vector 
00982   theDecayRate.SetZ(theZ);
00983   theDecayRate.SetA(theA);
00984   theDecayRate.SetE(theE);
00985   theDecayRate.SetGeneration(theG);
00986   theDecayRate.SetDecayRateC(theRates);
00987   theDecayRate.SetTaos(theTaos);
00988 }
00990 //
00991 // 
00992 void DsG4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition &theParentNucleus)
00993 {
00994   // 1) To calculate all the coefficiecies required to derive the radioactivities for all 
00995   // progeny of theParentNucleus
00996   //
00997   // 2) Add the coefficiencies to the decay rate table vector 
00998   //
00999   
01000   //
01001   // Create and initialise variables used in the method.
01002   //
01003 
01004   theDecayRateVector.clear();
01005   
01006   G4int nGeneration = 0;
01007   std::vector<G4double> rates;
01008   std::vector<G4double> taos;
01009   
01010   // start rate is -1.
01011   rates.push_back(-1.);
01012   //
01013   //
01014   G4int A = ((const G4Ions*)(&theParentNucleus))->GetAtomicMass();
01015   G4int Z = ((const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
01016   G4double E = ((const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
01017   G4double tao = theParentNucleus.GetPDGLifeTime();
01018   taos.push_back(tao);
01019   G4int nEntry = 0;
01020   
01021   //fill the decay rate with the intial isotope data
01022   SetDecayRate(Z,A,E,nGeneration,rates,taos);
01023 
01024   // store the decay rate in decay rate vector
01025   theDecayRateVector.push_back(theDecayRate);
01026   nEntry++;
01027 
01028   // now start treating the sencondary generations..
01029 
01030   G4bool stable = false;
01031   G4int i;
01032   G4int j;
01033   G4VDecayChannel       *theChannel             = 0;
01034   G4NuclearDecayChannel *theNuclearDecayChannel = 0;
01035   G4ITDecayChannel *theITChannel = 0;
01036   G4BetaMinusDecayChannel *theBetaMinusChannel = 0;
01037   G4BetaPlusDecayChannel *theBetaPlusChannel = 0;
01038   G4AlphaDecayChannel *theAlphaChannel = 0;
01039   G4RadioactiveDecayMode theDecayMode;
01040   //  G4NuclearLevelManager levelManager;
01041   //const G4NuclearLevel* level;
01042   G4double theBR = 0.0;
01043   G4int AP = 0;
01044   G4int ZP = 0;
01045   G4int AD = 0;
01046   G4int ZD = 0;
01047   G4double EP = 0.;
01048   std::vector<G4double> TP;
01049   std::vector<G4double> RP;
01050   G4ParticleDefinition *theDaughterNucleus;
01051   G4double daughterExcitation;
01052   G4ParticleDefinition *aParentNucleus;
01053   G4IonTable* theIonTable;
01054   G4DecayTable *aTempDecayTable;
01055   G4double theRate;
01056   G4double TaoPlus;
01057   G4int nS = 0;
01058   G4int nT = nEntry;
01059   G4double brs[7];
01060   //
01061   theIonTable = (G4IonTable *)(G4ParticleTable::GetParticleTable()->GetIonTable());
01062  
01063   while (!stable) {
01064     nGeneration++;
01065     for (j = nS; j< nT; j++) {
01066       ZP = theDecayRateVector[j].GetZ();
01067       AP = theDecayRateVector[j].GetA();
01068       EP = theDecayRateVector[j].GetE();
01069       RP = theDecayRateVector[j].GetDecayRateC();
01070       TP = theDecayRateVector[j].GetTaos();      
01071       if (GetVerboseLevel()>0){
01072         G4cout <<"DsG4RadioactiveDecay::AddDecayRateTable : "
01073                << " daughters of ("<< ZP <<", "<<AP<<", "
01074                << EP <<") "
01075                << " are being calculated. "       
01076                <<" generation = "
01077                << nGeneration << G4endl;
01078       }
01079       aParentNucleus = theIonTable->GetIon(ZP,AP,EP);
01080       if (!IsLoaded(*aParentNucleus)){
01081         aParentNucleus->SetDecayTable(LoadDecayTable(*aParentNucleus));
01082       }
01083       aTempDecayTable = aParentNucleus->GetDecayTable();
01084       //
01085       //
01086       // Go through the decay table and to combine the same decay channels
01087       //
01088       for (i=0; i< 7; i++) brs[i] = 0.0;
01089       
01090       G4DecayTable *theDecayTable = new G4DecayTable();
01091       
01092       for (i=0; i<aTempDecayTable->entries(); i++) {
01093         theChannel             = aTempDecayTable->GetDecayChannel(i);
01094         theNuclearDecayChannel = static_cast<G4NuclearDecayChannel *>(theChannel);
01095         theDecayMode           = theNuclearDecayChannel->GetDecayMode();
01096         daughterExcitation = theNuclearDecayChannel->GetDaughterExcitation ();
01097         theDaughterNucleus = theNuclearDecayChannel->GetDaughterNucleus () ;
01098         AD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
01099         ZD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();  
01100         G4NuclearLevelManager * levelManager = G4NuclearLevelStore::GetInstance()->GetManager (ZD, AD);
01101         if ( levelManager->NumberOfLevels() ) {
01102           const G4NuclearLevel* level = levelManager->NearestLevel (daughterExcitation);
01103 
01104           if (std::abs(daughterExcitation - level->Energy()) < levelTolerance) {
01105             
01106             // Level hafe life is in ns and I want to set the gate as 1 micros
01107             if ( theDecayMode == 0 && level->HalfLife() >= 1000.){    
01108               // some further though may needed here
01109               theDecayTable->Insert(theChannel);
01110             } 
01111             else{
01112               brs[theDecayMode] += theChannel->GetBR();
01113             }
01114           }
01115           else {
01116             brs[theDecayMode] += theChannel->GetBR();
01117           }
01118         }
01119         else{
01120           brs[theDecayMode] += theChannel->GetBR();
01121         }
01122       }     
01123       brs[2] = brs[2]+brs[3]+brs[4]+brs[5];
01124       brs[3] = brs[4] =brs[5] =  0.0;
01125       for (i= 0; i<7; i++){
01126         if (brs[i] > 0) {
01127           switch ( i ) {
01128           case 0:
01129             //
01130             //
01131             // Decay mode is isomeric transition.
01132             //
01133             
01134             theITChannel =  new G4ITDecayChannel
01135               (0, (const G4Ions*) aParentNucleus, brs[0]);
01136             
01137             theDecayTable->Insert(theITChannel);
01138             break;
01139             
01140           case 1:
01141             //
01142             //
01143             // Decay mode is beta-.
01144             //
01145             theBetaMinusChannel = new G4BetaMinusDecayChannel (0, aParentNucleus,
01146                                                                brs[1], 0.*MeV, 0.*MeV, 1, false, 0);
01147             theDecayTable->Insert(theBetaMinusChannel);
01148             
01149             break;
01150             
01151           case 2:
01152             //
01153             //
01154             // Decay mode is beta+ + EC.
01155             //
01156             theBetaPlusChannel = new G4BetaPlusDecayChannel (GetVerboseLevel(), aParentNucleus,
01157                                                              brs[2], 0.*MeV, 0.*MeV, 1, false, 0);
01158             theDecayTable->Insert(theBetaPlusChannel);
01159             break;                    
01160             
01161           case 6:
01162             //
01163             //
01164             // Decay mode is alpha.
01165             //
01166             theAlphaChannel = new G4AlphaDecayChannel (GetVerboseLevel(), aParentNucleus,
01167                                                        brs[6], 0.*MeV, 0.*MeV);
01168             theDecayTable->Insert(theAlphaChannel);
01169             break;
01170             
01171           default:
01172             break;
01173           }
01174         }
01175       }
01176         
01177       // 
01178       // loop over all braches in theDecayTable
01179       //
01180       for ( i=0; i<theDecayTable->entries(); i++){
01181         theChannel             = theDecayTable->GetDecayChannel(i);
01182         theNuclearDecayChannel = static_cast<G4NuclearDecayChannel *>(theChannel);
01183         theBR = theChannel->GetBR();
01184         theDaughterNucleus = theNuclearDecayChannel->GetDaughterNucleus();
01185         
01186         //
01187         // now test if the daughterNucleus is a valid one
01188         //
01189         if (IsApplicable(*theDaughterNucleus) && theBR 
01190             && aParentNucleus != theDaughterNucleus ) {
01191           // need to make sure daugher has decaytable
01192           if (!IsLoaded(*theDaughterNucleus)){
01193             theDaughterNucleus->SetDecayTable(LoadDecayTable(*theDaughterNucleus));
01194           }
01195           if (theDaughterNucleus->GetDecayTable()->entries() ) {
01196             //
01197             A = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
01198             Z = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
01199             E = ((const G4Ions*)(theDaughterNucleus))->GetExcitationEnergy();
01200           
01201             TaoPlus = theDaughterNucleus->GetPDGLifeTime();
01202             //          cout << TaoPlus <<G4endl;
01203             if (TaoPlus > 0.) {
01204               // first set the taos, one simply need to add to the parent ones
01205               taos.clear();
01206               taos = TP;
01207               taos.push_back(TaoPlus);
01208               // now calculate the coefficiencies
01209               //
01210               // they are in two parts, first the les than n ones
01211               rates.clear();
01212               size_t k;
01213               for (k = 0; k < RP.size(); k++){
01214                 theRate = TP[k]/(TP[k]-TaoPlus) * theBR * RP[k];
01215                 rates.push_back(theRate);
01216               }
01217               //
01218               // the sencond part: the n:n coefficiency
01219               theRate = 0.;
01220               for (k = 0; k < RP.size(); k++){
01221                 theRate -=TaoPlus/(TP[k]-TaoPlus) * theBR * RP[k];
01222               }
01223               rates.push_back(theRate);               
01224               SetDecayRate (Z,A,E,nGeneration,rates,taos);
01225               theDecayRateVector.push_back(theDecayRate);
01226               nEntry++;
01227             } 
01228           }
01229         }  
01230         // end of testing daughter nucleus
01231       }
01232       // end of i loop( the branches) 
01233     }
01234     //end of for j loop
01235     nS = nT;
01236     nT = nEntry;
01237     if (nS == nT) stable = true;
01238   }
01239   
01240   //end of while loop
01241   // the calculation completed here
01242   
01243   
01244   // fill the first part of the decay rate table
01245   // which is the name of the original particle (isotope) 
01246   //
01247   theDecayRateTable.SetIonName(theParentNucleus.GetParticleName()); 
01248   //
01249   //
01250   // now fill the decay table with the newly completed decay rate vector
01251   //
01252   
01253   theDecayRateTable.SetItsRates(theDecayRateVector);
01254   
01255   //
01256   // finally add the decayratetable to the tablevector
01257   //
01258   theDecayRateTableVector.push_back(theDecayRateTable);
01259 }
01260   
01262 //
01263 //
01264 // SetSourceTimeProfile
01265 //
01266 //  read in the source time profile function (histogram)
01267 //
01268 
01269 void DsG4RadioactiveDecay::SetSourceTimeProfile(G4String filename)
01270 {
01271   std::ifstream infile ( filename, std::ios::in );
01272   if ( !infile ) G4Exception(__FILE__, G4inttostring(__LINE__), FatalException,  "Unable to open source data file" );
01273   
01274   float bin, flux;
01275   NSourceBin = -1;
01276   while (infile >> bin >> flux ) {
01277     NSourceBin++;
01278     if (NSourceBin > 99)  G4Exception(__FILE__, G4inttostring(__LINE__), FatalException,  "input source data file too big (>100 rows)" );
01279     SBin[NSourceBin] = bin * s;
01280     SProfile[NSourceBin] = flux;
01281   }
01282   SetAnalogueMonteCarlo(0);
01283 #ifdef G4VERBOSE
01284   if (GetVerboseLevel()>1)
01285     {G4cout <<" Source Timeprofile Nbin = " << NSourceBin <<G4endl;}
01286 #endif
01287 }
01288 
01290 //
01291 //
01292 // SetDecayBiasProfile
01293 //
01294 // read in the decay bias scheme function (histogram)
01295 //
01296 void DsG4RadioactiveDecay::SetDecayBias(G4String filename)
01297 {
01298   std::ifstream infile ( filename, std::ios::in);
01299   if ( !infile ) G4Exception(__FILE__, G4inttostring(__LINE__), FatalException,  "Unable to open bias data file" );
01300   
01301   float bin, flux;
01302   NDecayBin = -1;
01303   while (infile >> bin >> flux ) {
01304     NDecayBin++;
01305     if (NDecayBin > 99)  G4Exception(__FILE__, G4inttostring(__LINE__), FatalException,  "input bias data file too big (>100 rows)" );
01306     DBin[NDecayBin] = bin * s;
01307     DProfile[NDecayBin] = flux;
01308   }
01309   G4int i ;
01310   for ( i = 1; i<= NDecayBin; i++) DProfile[i] += DProfile[i-1];
01311   for ( i = 0; i<= NDecayBin; i++) DProfile[i] /= DProfile[NDecayBin];
01312   SetAnalogueMonteCarlo(0);
01313 #ifdef G4VERBOSE
01314   if (GetVerboseLevel()>1)
01315     {G4cout <<" Decay Bias Profile  Nbin = " << NDecayBin <<G4endl;}
01316 #endif
01317 }
01318 
01320 //
01321 //
01322 // DecayIt
01323 //
01324 G4VParticleChange* DsG4RadioactiveDecay::DecayIt(const G4Track& theTrack, const G4Step& )
01325 {
01326   //
01327   // Initialize the G4ParticleChange object. Get the particle details and the
01328   // decay table.
01329   //
01330   fParticleChangeForRadDecay.Initialize(theTrack);
01331   const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
01332   G4ParticleDefinition *theParticleDef = theParticle->GetDefinition();
01333 
01334   // First check whether RDM applies to the current logical volume
01335   //
01336   if(!std::binary_search(ValidVolumes.begin(),
01337                     ValidVolumes.end(), 
01338                     theTrack.GetVolume()->GetLogicalVolume()->GetName()))
01339     {
01340 #ifdef G4VERBOSE
01341       if (GetVerboseLevel()>0)
01342         {
01343           G4cout <<"DsG4RadioactiveDecay::DecayIt : "
01344                  << theTrack.GetVolume()->GetLogicalVolume()->GetName()
01345                  << " is not selected for the RDM"<< G4endl;
01346           G4cout << " There are " << ValidVolumes.size() << " volumes" << G4endl;
01347           G4cout << " The Valid volumes are " << G4endl;
01348           for (size_t i = 0; i< ValidVolumes.size(); i++)
01349             G4cout << ValidVolumes[i] << G4endl;
01350         }
01351 #endif
01352       fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
01353       //
01354       //
01355       // Kill the parent particle.
01356       //
01357       fParticleChangeForRadDecay.ProposeTrackStatus( fStopAndKill ) ;
01358       fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
01359       ClearNumberOfInteractionLengthLeft();
01360       return &fParticleChangeForRadDecay;
01361     }
01362    
01363   // now check is the particle is valid for RDM
01364   //
01365   if (!(IsApplicable(*theParticleDef)))
01366     { 
01367       //
01368       // The particle is not a Ion or outside the nucleuslimits for decay
01369       //
01370 #ifdef G4VERBOSE
01371       if (GetVerboseLevel()>0)
01372         {
01373           G4cerr <<"DsG4RadioactiveDecay::DecayIt : "
01374                  <<theParticleDef->GetParticleName() 
01375                  << " is not a valid nucleus for the RDM"<< G4endl;
01376         }
01377 #endif
01378       fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
01379       //
01380       //
01381       // Kill the parent particle.
01382       //
01383       fParticleChangeForRadDecay.ProposeTrackStatus( fStopAndKill ) ;
01384       fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
01385       ClearNumberOfInteractionLengthLeft();
01386       return &fParticleChangeForRadDecay;
01387     }
01388   
01389   if (!IsLoaded(*theParticleDef))
01390     {
01391       theParticleDef->SetDecayTable(LoadDecayTable(*theParticleDef));
01392     }
01393   G4DecayTable *theDecayTable = theParticleDef->GetDecayTable();
01394   
01395   if  (theDecayTable == 0 || theDecayTable->entries() == 0 )
01396     {
01397       //
01398       //
01399       // There are no data in the decay table.  Set the particle change parameters
01400       // to indicate this.
01401       //
01402 #ifdef G4VERBOSE
01403       if (GetVerboseLevel()>0)
01404         {
01405           G4cerr <<"DsG4RadioactiveDecay::DecayIt : decay table not defined  for ";
01406           G4cerr <<theParticleDef->GetParticleName() <<G4endl;
01407         }
01408 #endif
01409       fParticleChangeForRadDecay.SetNumberOfSecondaries(0);
01410       //
01411       //
01412       // Kill the parent particle.
01413       //
01414       fParticleChangeForRadDecay.ProposeTrackStatus( fStopAndKill ) ;
01415       fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(0.0);
01416       ClearNumberOfInteractionLengthLeft();
01417       return &fParticleChangeForRadDecay;
01418     }
01419   else 
01420     { 
01421       //
01422       // now try to  decay it
01423       //
01424       G4double energyDeposit = 0.0;
01425       G4double finalGlobalTime = theTrack.GetGlobalTime();
01426       G4int index;
01427       G4ThreeVector currentPosition;
01428       currentPosition = theTrack.GetPosition();
01429 
01430 //======================================= Begin dayabay ==========================================
01431       // decay for He8 and Li9
01432       if((theParticleDef->GetParticleName()).find("He8") != std::string::npos || (theParticleDef->GetParticleName()).find("Li9") != std::string::npos) {
01433 #ifdef G4VERBOSE
01434         if (GetVerboseLevel()>0)
01435           {
01436             G4cout <<"DecayIt:  Dayabay MC version " << G4endl;
01437           }
01438 #endif
01439 
01440         G4DecayProducts *products = 0;
01441 
01442         G4double decayTime = 0.0*ns;
01443         if((theParticleDef->GetParticleName()).find("He8") != std::string::npos)  {
01444           products = DoHe8Decay(*theParticleDef);
01445           decayTime = CLHEP::RandExponential::shoot(0.12/0.693*1000000000.)*ns;
01446         }
01447         if((theParticleDef->GetParticleName()).find("Li9") != std::string::npos)  {
01448           products = DoLi9Decay(*theParticleDef);
01449           decayTime = CLHEP::RandExponential::shoot(0.18/0.693*1000000000.)*ns;
01450         }
01451 
01452         //
01453         //
01454         // Get parent particle information and boost the decay products to the
01455         // laboratory frame based on this information.
01456         //
01457         G4double ParentEnergy = theParticle->GetTotalEnergy();
01458         G4ThreeVector ParentDirection(theParticle->GetMomentumDirection());
01459 
01460         if (theTrack.GetTrackStatus() == fStopButAlive )
01461           {
01462             //
01463             //
01464             // The particle is decayed at rest.
01465             //
01466             // since the time is still for rest particle in G4 we need to add the additional 
01467             // time lapsed between the particle come to rest and the actual decay. This time 
01468             // is simply sampled with the mean-life of the particle.
01469             //
01470             //finalGlobalTime += -std::log( G4UniformRand()) * theParticleDef->GetPDGLifeTime() ;
01471             finalGlobalTime += decayTime;
01472             energyDeposit += theParticle->GetKineticEnergy();
01473           }
01474         else
01475           {
01476             //
01477             //
01478             // The particle is decayed in flight (PostStep case).
01479             //
01480             finalGlobalTime += decayTime;
01481             products->Boost( ParentEnergy, ParentDirection);
01482           }
01483         //
01484         //
01485         // Add products in theParticleChangeForRadDecay.
01486         //
01487         G4int numberOfSecondaries = products->entries();
01488         fParticleChangeForRadDecay.SetNumberOfSecondaries(numberOfSecondaries);
01489 #ifdef G4VERBOSE
01490         if (GetVerboseLevel()>1) {
01491           G4cout <<"DsG4RadioactiveDecay::DecayIt : Decay vertex :";
01492           G4cout <<" Time: " <<finalGlobalTime/ns <<"[ns]";
01493           G4cout <<" X:" <<(theTrack.GetPosition()).x() /cm <<"[cm]";
01494           G4cout <<" Y:" <<(theTrack.GetPosition()).y() /cm <<"[cm]";
01495           G4cout <<" Z:" <<(theTrack.GetPosition()).z() /cm <<"[cm]";
01496           G4cout <<G4endl;
01497           G4cout <<"G4Decay::DecayIt  : decay products in Lab. Frame" <<G4endl;
01498           products->DumpInfo();
01499         }
01500 #endif
01501         for (index=0; index < numberOfSecondaries; index++)
01502           {
01503             G4Track* secondary = new G4Track
01504               (products->PopProducts(), finalGlobalTime, currentPosition);
01505             secondary->SetGoodForTrackingFlag();
01506                         secondary->SetTouchableHandle(theTrack.GetTouchableHandle());
01507             fParticleChangeForRadDecay.AddSecondary(secondary);
01508           }
01509         delete products;
01510 
01511         //
01512         // Kill the parent particle.
01513         //
01514         fParticleChangeForRadDecay.ProposeTrackStatus( fStopAndKill ) ;
01515         fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(energyDeposit);
01516         // 
01517         fParticleChangeForRadDecay.ProposeGlobalTime( finalGlobalTime );
01518         //
01519         // Reset NumberOfInteractionLengthLeft.
01520         //
01521         ClearNumberOfInteractionLengthLeft();
01522 
01523         return &fParticleChangeForRadDecay ;
01524       }
01525 //=======================================  End dayabay  ==========================================
01526       
01527       // check whether use Analogue or VR implementation
01528       //
01529       if (AnalogueMC){
01530         //
01531         // Aanalogue MC 
01532 #ifdef G4VERBOSE
01533         if (GetVerboseLevel()>0)
01534           {
01535             G4cout <<"DecayIt:  Analogue MC version " << G4endl;
01536           }
01537 #endif
01538         //
01539         G4DecayProducts *products = DoDecay(*theParticleDef);
01540         //
01541         //
01542         // Get parent particle information and boost the decay products to the
01543         // laboratory frame based on this information.
01544         //
01545         G4double ParentEnergy = theParticle->GetTotalEnergy();
01546         G4ThreeVector ParentDirection(theParticle->GetMomentumDirection());
01547         
01548         if (theTrack.GetTrackStatus() == fStopButAlive )
01549           {
01550             //
01551             //
01552             // The particle is decayed at rest.
01553             //
01554             // since the time is still for rest particle in G4 we need to add the additional 
01555             // time lapsed between the particle come to rest and the actual decay. This time 
01556             // is simply sampled with the mean-life of the particle.
01557             //
01558             finalGlobalTime += -std::log( G4UniformRand()) * theParticleDef->GetPDGLifeTime() ;
01559             energyDeposit += theParticle->GetKineticEnergy();
01560           }
01561         else
01562           {
01563             //
01564             //
01565             // The particle is decayed in flight (PostStep case).
01566             //
01567             products->Boost( ParentEnergy, ParentDirection);
01568           }
01569         //
01570         //
01571         // Add products in theParticleChangeForRadDecay.
01572         //
01573         G4int numberOfSecondaries = products->entries();
01574         fParticleChangeForRadDecay.SetNumberOfSecondaries(numberOfSecondaries);
01575 #ifdef G4VERBOSE
01576         if (GetVerboseLevel()>1) {
01577           G4cout <<"DsG4RadioactiveDecay::DecayIt : Decay vertex :";
01578           G4cout <<" Time: " <<finalGlobalTime/ns <<"[ns]";
01579           G4cout <<" X:" <<(theTrack.GetPosition()).x() /cm <<"[cm]";
01580           G4cout <<" Y:" <<(theTrack.GetPosition()).y() /cm <<"[cm]";
01581           G4cout <<" Z:" <<(theTrack.GetPosition()).z() /cm <<"[cm]";
01582           G4cout <<G4endl;
01583           G4cout <<"G4Decay::DecayIt  : decay products in Lab. Frame" <<G4endl;
01584           products->DumpInfo();
01585         }
01586 #endif
01587         for (index=0; index < numberOfSecondaries; index++) 
01588           {
01589             G4Track* secondary = new G4Track
01590               (products->PopProducts(), finalGlobalTime, currentPosition);
01591             secondary->SetGoodForTrackingFlag();
01592                         secondary->SetTouchableHandle(theTrack.GetTouchableHandle());
01593             fParticleChangeForRadDecay.AddSecondary(secondary);
01594           }
01595         delete products;
01596         //
01597         // end of analogue MC algarithm
01598         //
01599       }
01600       else {
01601         //
01602         // Varaice Reduction Method
01603         //
01604 #ifdef G4VERBOSE
01605         if (GetVerboseLevel()>0)
01606           {
01607             G4cout <<"DecayIt:  Variance Reduction version " << G4endl;
01608           }
01609 #endif
01610         if (!IsRateTableReady(*theParticleDef)) {
01611           // if the decayrates are not ready, calculate them and 
01612           // add to the rate table vector 
01613           AddDecayRateTable(*theParticleDef);
01614         }
01615         //retrieve the rates 
01616         GetDecayRateTable(*theParticleDef);
01617         //
01618         // declare some of the variables required in the implementation
01619         //
01620         G4ParticleDefinition* parentNucleus;
01621         G4IonTable *theIonTable;
01622         G4int PZ;
01623         G4int PA;
01624         G4double PE;
01625         std::vector<G4double> PT;
01626         std::vector<G4double> PR;
01627         G4double taotime;
01628         G4double decayRate;
01629         
01630         size_t i;
01631         size_t j;
01632         G4int numberOfSecondaries;
01633         G4int totalNumberOfSecondaries = 0;
01634         G4double currentTime = 0.;
01635         G4int ndecaych;
01636         G4DynamicParticle* asecondaryparticle;
01637         //      G4DecayProducts* products = 0;
01638         std::vector<G4DynamicParticle*> secondaryparticles;
01639         std::vector<G4double> pw;
01640         std::vector<G4double> ptime;
01641         pw.clear();
01642         ptime.clear();
01643         //now apply the nucleus splitting
01644         //
01645         //
01646         for (G4int n = 0; n < NSplit; n++)
01647           {
01648             /*
01649             //
01650             // Get the decay time following the decay probability function 
01651             // suppllied by user
01652             //
01653             G4double theDecayTime = GetDecayTime();
01654             
01655             G4int nbin = GetDecayTimeBin(theDecayTime);
01656             
01657             // claculate the first part of the weight function
01658             
01659             G4double weight1 =1./DProfile[nbin-1] 
01660               *(DBin[nbin]-DBin[nbin-1])
01661               /NSplit;
01662             if (nbin > 1) {
01663                weight1 = 1./(DProfile[nbin]-DProfile[nbin-2])
01664                  *(DBin[nbin]-DBin[nbin-1])
01665                  /NSplit;}
01666             // it should be calculated in seconds
01667             weight1 /= s ;
01668             */
01669             //
01670             // loop over all the possible secondaries of the nucleus
01671             // the first one is itself.
01672             //
01673             for ( i = 0; i<theDecayRateVector.size(); i++){
01674               PZ = theDecayRateVector[i].GetZ();
01675               PA = theDecayRateVector[i].GetA();
01676               PE = theDecayRateVector[i].GetE();
01677               PT = theDecayRateVector[i].GetTaos();
01678               PR = theDecayRateVector[i].GetDecayRateC();
01679 
01680               //
01681               // Get the decay time following the decay probability function 
01682               // suppllied by user
01683               //
01684               G4double theDecayTime = GetDecayTime();
01685               
01686               G4int nbin = GetDecayTimeBin(theDecayTime);
01687               
01688               // claculate the first part of the weight function
01689               
01690               G4double weight1 =1./DProfile[nbin-1] 
01691                 *(DBin[nbin]-DBin[nbin-1])
01692                 /NSplit;
01693               if (nbin > 1) {
01694                 weight1 = 1./(DProfile[nbin]-DProfile[nbin-2])
01695                   *(DBin[nbin]-DBin[nbin-1])
01696                   /NSplit;}
01697               // it should be calculated in seconds
01698               weight1 /= s ;
01699               
01700               // a temprary products buffer and its contents is transfered to 
01701               // the products at the end of the loop
01702               //
01703               G4DecayProducts *tempprods = 0;
01704               
01705               // calculate the decay rate of the isotope
01706               // one need to fold the the source bias function with the decaytime
01707               //
01708               decayRate = 0.;
01709               for ( j = 0; j < PT.size(); j++){
01710                 taotime = GetTaoTime(theDecayTime,PT[j]);
01711                 decayRate -= PR[j] * taotime;
01712               }
01713               
01714               // decayRatehe radioactivity of isotope (PZ,PA,PE) at the 
01715               // time 'theDecayTime'
01716               // it will be used to calculate the statistical weight of the 
01717               // decay products of this isotope
01718               
01719               
01720               //
01721               // now calculate the statistical weight
01722               //
01723               
01724               G4double weight = weight1*decayRate; 
01725               // decay the isotope 
01726               theIonTable = (G4IonTable *)(G4ParticleTable::GetParticleTable()->GetIonTable());
01727               parentNucleus = theIonTable->GetIon(PZ,PA,PE);
01728               
01729               // decide whther to apply branching ratio bias or not
01730               //
01731               if (BRBias){
01732                 G4DecayTable *theDecayTable = parentNucleus->GetDecayTable();
01733                 ndecaych = G4int(theDecayTable->entries()*G4UniformRand());
01734                 G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(ndecaych);
01735                 if (theDecayChannel == 0)
01736                   {
01737                     // Decay channel not found.
01738 #ifdef G4VERBOSE
01739                     if (GetVerboseLevel()>0)
01740                       {
01741                         G4cerr <<"DsG4RadioactiveDecay::DoIt : can not determine decay channel";
01742                         G4cerr <<G4endl;
01743                         theDecayTable ->DumpInfo();
01744                       }
01745 #endif
01746                   }
01747                 else
01748                   {
01749                     // A decay channel has been identified, so execute the DecayIt.
01750                     G4double tempmass = parentNucleus->GetPDGMass();      
01751                     tempprods = theDecayChannel->DecayIt(tempmass);
01752                     weight *= (theDecayChannel->GetBR())*(theDecayTable->entries());
01753                   }
01754               }
01755               else {
01756                 tempprods = DoDecay(*parentNucleus);
01757               }
01758               //
01759               // save the secondaries for buffers
01760               //
01761               numberOfSecondaries = tempprods->entries();
01762               currentTime = finalGlobalTime + theDecayTime;
01763               for (index=0; index < numberOfSecondaries; index++) 
01764                 {
01765                   asecondaryparticle = tempprods->PopProducts();
01766                   if (asecondaryparticle->GetDefinition()->GetBaryonNumber() < 5){
01767                     pw.push_back(weight);
01768                     ptime.push_back(currentTime);
01769                     secondaryparticles.push_back(asecondaryparticle);
01770                   }
01771                 }
01772               //
01773               delete tempprods;
01774               
01775               //end of i loop
01776             }
01777             
01778             // end of n loop 
01779           } 
01780         // now deal with the secondaries in the two stl containers
01781         // and submmit them back to the tracking manager
01782         //
01783         totalNumberOfSecondaries = pw.size();
01784         fParticleChangeForRadDecay.SetNumberOfSecondaries(totalNumberOfSecondaries);
01785         for (index=0; index < totalNumberOfSecondaries; index++) 
01786           { 
01787             G4Track* secondary = new G4Track(
01788                                              secondaryparticles[index], ptime[index], currentPosition);
01789             secondary->SetGoodForTrackingFlag();           
01790                         secondary->SetTouchableHandle(theTrack.GetTouchableHandle());
01791             secondary->SetWeight(pw[index]);       
01792             fParticleChangeForRadDecay.AddSecondary(secondary); 
01793           }
01794         //
01795         // make sure the original track is set to stop and its kinematic energy collected
01796         // 
01797         //theTrack.SetTrackStatus(fStopButAlive);
01798         //energyDeposit += theParticle->GetKineticEnergy();
01799         
01800       }
01801     
01802       //
01803       // Kill the parent particle.
01804       //
01805       fParticleChangeForRadDecay.ProposeTrackStatus( fStopAndKill ) ;
01806       fParticleChangeForRadDecay.ProposeLocalEnergyDeposit(energyDeposit);
01807       // 
01808       fParticleChangeForRadDecay.ProposeGlobalTime( finalGlobalTime );
01809       //
01810       // Reset NumberOfInteractionLengthLeft.
01811       //
01812       ClearNumberOfInteractionLengthLeft();
01813       
01814       return &fParticleChangeForRadDecay ;
01815     }
01816 } 
01817 
01819 //
01820 //
01821 // DoDecay
01822 //
01823 G4DecayProducts* DsG4RadioactiveDecay::DoDecay(  G4ParticleDefinition& theParticleDef )
01824 {
01825   G4DecayProducts *products = 0;
01826   //
01827   //
01828   // follow the decaytable and generate the secondaries...
01829   // 
01830   //
01831 #ifdef G4VERBOSE
01832   if (GetVerboseLevel()>0)
01833     {
01834       G4cout<<"Begin of DoDecay..."<<G4endl;
01835     }
01836 #endif
01837   G4DecayTable *theDecayTable = theParticleDef.GetDecayTable();
01838   //
01839   // Choose a decay channel.
01840   //
01841 #ifdef G4VERBOSE
01842   if (GetVerboseLevel()>0)
01843     {
01844       G4cout <<"Selecte a channel..."<<G4endl;
01845     }
01846 #endif
01847   G4VDecayChannel *theDecayChannel = theDecayTable->SelectADecayChannel();
01848   if (theDecayChannel == 0)
01849     {
01850       // Decay channel not found.
01851       //
01852       G4cerr <<"DsG4RadioactiveDecay::DoIt : can not determine decay channel";
01853       G4cerr <<G4endl;
01854       theDecayTable ->DumpInfo();
01855     }
01856       else
01857     {
01858       //
01859       // A decay channel has been identified, so execute the DecayIt.
01860       //
01861 #ifdef G4VERBOSE
01862       if (GetVerboseLevel()>1)
01863         {
01864           G4cerr <<"DsG4RadioactiveDecay::DoIt : selected decay channel  addr:";
01865           G4cerr <<theDecayChannel <<G4endl;
01866         }
01867 #endif
01868       
01869       G4double tempmass = theParticleDef.GetPDGMass();
01870       //
01871       
01872       products = theDecayChannel->DecayIt(tempmass);
01873       
01874     }
01875   return products;
01876 
01877 }
01878 
01879 //================================== Begin dayabay =============================================
01880 G4DecayProducts* DsG4RadioactiveDecay::DoHe8Decay( G4ParticleDefinition& theParticleDef) 
01881 {
01882   // create parent particle at rest
01883   G4ParticleMomentum dummy;
01884   G4DynamicParticle* parentparticle = new G4DynamicParticle( &theParticleDef, dummy, 0.0);
01885   G4DecayProducts* products = new G4DecayProducts(*parentparticle);
01886   delete parentparticle;
01887   //
01888   //
01889   // follow the decaytable and generate the secondaries...
01890   // 
01891   //
01892 #ifdef G4VERBOSE
01893   if (GetVerboseLevel()>0)
01894   {
01895     G4cout<<"Begin of DoHe8Decay..., using decay channels from dayabay!!!"<<G4endl;
01896   }
01897 #endif
01898 
01899   G4ThreeVector pElectron(0,0,0);
01900   G4ThreeVector pNeutron(0,0,0);
01901   G4ThreeVector pGamma(0,0,0);
01902 
01903   m_Li9He8->He8Decay(pElectron, pNeutron, pGamma, m_completedecay);
01904 
01905   G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
01906 
01907   if( pElectron.mag2()>0 ) 
01908   {
01909     G4ParticleDefinition* particle = particleTable->FindParticle("e-");
01910     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pElectron);
01911     products->PushProducts(daughterparticle);
01912   }
01913 
01914   if( pNeutron.mag2()>0 )
01915   {
01916     G4ParticleDefinition* particle = particleTable->FindParticle("neutron");
01917     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pNeutron);
01918     products->PushProducts(daughterparticle);
01919   }
01920 
01921   if( pGamma.mag2()>0 )
01922   {
01923     G4ParticleDefinition* particle = particleTable->FindParticle("gamma");
01924     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pGamma);
01925     products->PushProducts(daughterparticle);
01926   }
01927 
01928   return products;
01929 }
01930 
01931 G4DecayProducts* DsG4RadioactiveDecay::DoLi9Decay( G4ParticleDefinition& theParticleDef) 
01932 {
01933   // create parent particle at rest
01934   G4ParticleMomentum dummy;
01935   G4DynamicParticle* parentparticle = new G4DynamicParticle( &theParticleDef, dummy, 0.0);
01936   G4DecayProducts* products = new G4DecayProducts(*parentparticle);
01937   delete parentparticle;
01938   //
01939   //
01940   // follow the decaytable and generate the secondaries...
01941   // 
01942   //
01943 #ifdef G4VERBOSE
01944   if (GetVerboseLevel()>0)
01945   {
01946     G4cout<<"Begin of DoHe8Decay..., using decay channels from dayabay!!!"<<G4endl;
01947   }
01948 #endif
01949 
01950   G4ThreeVector pElectron(0,0,0);
01951   G4ThreeVector pNeutron(0,0,0);
01952   G4ThreeVector pAlpha1(0,0,0);
01953   G4ThreeVector pAlpha2(0,0,0);
01954 
01955   G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
01956   G4double alpha_mass = particleTable->FindParticle("alpha")->GetPDGMass();
01957 
01958   m_Li9He8->Li9Decay(pElectron, pNeutron, pAlpha1, pAlpha2, alpha_mass, m_completedecay);
01959 
01960   if( pElectron.mag2()>0 )
01961   {
01962     G4ParticleDefinition* particle = particleTable->FindParticle("e-");
01963     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pElectron);
01964     products->PushProducts(daughterparticle);
01965   }
01966 
01967   if( pNeutron.mag2()>0 )
01968   {
01969     G4ParticleDefinition* particle = particleTable->FindParticle("neutron");
01970     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pNeutron);
01971     products->PushProducts(daughterparticle);
01972   }
01973 
01974   if( pAlpha1.mag2()>0 )
01975   {
01976     G4ParticleDefinition* particle = particleTable->FindParticle("alpha");
01977     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pAlpha1);
01978     products->PushProducts(daughterparticle);
01979   }
01980 
01981   if( pAlpha2.mag2()>0 )
01982   { 
01983     G4ParticleDefinition* particle = particleTable->FindParticle("alpha");
01984     G4DynamicParticle * daughterparticle = new G4DynamicParticle( particle, pAlpha2);
01985     products->PushProducts(daughterparticle);
01986   }
01987 
01988   return products;
01989 }
01990 //================================== End dayabay =============================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:53:24 2011 for DetSim by doxygen 1.4.7