SetDecayInstance Class Reference

Inheritance diagram for SetDecayInstance:

BLCallback

List of all members.

Public Member Functions

 SetDecayInstance (G4String _particleName)
void callback (int type)
 callack() from BLCallback.
bool isMatch (G4String name, G4VDecayChannel *chan)
G4String decayChannelName (const G4VDecayChannel *channel)
 decayChannelName() returns the name of the channel.
void fatalError ()
 fatalError() arranges to abort the simulation after all callbacks have run.

Private Attributes

G4String particleName
double lifetime
std::vector< G4String > channel
std::vector< double > br

Static Private Attributes

static bool first = true

Friends

class BLCMDsetdecay


Constructor & Destructor Documentation

SetDecayInstance::SetDecayInstance ( G4String  _particleName  )  [inline]

References lifetime, and particleName.

00072                                                  : BLCallback(), channel(), br()
00073                 { particleName=_particleName; lifetime=-1.0; }


Member Function Documentation

void SetDecayInstance::callback ( int  type  )  [virtual]

callack() from BLCallback.

Reimplemented from BLCallback.

References BLAssert, br, channel, decayChannelName(), fatalError(), first, isMatch(), lifetime, particleName, BLCommand::printError(), and BLCommand::splitString().

Referenced by fatalError().

00163 {
00164         BLAssert(type==0);
00165 
00166         if(first) printf(
00167                 "************************************\n"
00168                 "***  Note Special Decays Below!  ***\n"
00169                 "************************************\n");
00170         first = false;
00171 
00172         G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable();
00173         G4ParticleDefinition *pd = particleTable->FindParticle(particleName);
00174         
00175         if(!pd) {
00176                 BLCommand::printError("setdecay: invalid particle '%s'\n",
00177                                                 particleName.c_str());
00178                 fatalError();
00179                 return;
00180         }
00181 
00182         printf("setdecay %s",particleName.c_str());
00183         if(lifetime >= 0.0) {
00184                 if(pd->IsShortLived()) {
00185                         printf(" (lifetime ignored for short-lived particles)");
00186                 } else {
00187                         pd->SetPDGLifeTime(lifetime); 
00188                         printf(" lifetime=%.4g ns",lifetime/ns);
00189                 }
00190         }
00191         printf("\n");
00192 
00193         // handle stable particles, adding Decay process if necessary
00194         if(pd->GetPDGStable())
00195                 pd->SetPDGStable(false);
00196         if(pd->GetDecayTable() == 0)
00197                 pd->SetDecayTable(new G4DecayTable());
00198         G4ProcessManager* pmanager = pd->GetProcessManager(); 
00199         G4ProcessVector *pv = pmanager->GetProcessList();
00200         bool hasDecay=false;
00201         for(int i=0; i<pv->entries(); ++i) {
00202                 G4VProcess *p=(*pv)[i];
00203                 if(p->GetProcessName() == "Decay") {
00204                         hasDecay = true;
00205                         break;
00206                 }
00207         }
00208         if(!hasDecay) {
00209                 if(pd->GetPDGLifeTime() < 0.0) {
00210                         printf("  *** Must specify lifetime!\n");
00211                         fatalError();
00212                         return;
00213                 }
00214                 printf("  Decay process added to previously-stable particle\n");
00215                 G4VProcess* aDecay = new G4Decay();
00216                 pmanager->AddProcess(aDecay);
00217                 pmanager->SetProcessOrdering(aDecay, idxPostStep, 5);
00218                 pmanager->SetProcessOrdering(aDecay, idxAtRest);
00219         }
00220 
00221         // no channels specified means keep the existing ones.
00222         if(channel.size() == 0) {
00223                 printf("\n");
00224                 return;
00225         }
00226 
00227         // Create new decay table (based on the original decay table).
00228         // Channels found in orgDecayTable are re-used with updated branching 
00229         // ratio; channels not found are created ("generic" phase space decay).
00230         // These loops handle multiple matching channels in orgDecayTable.
00231         G4DecayTable *orgDecayTable = pd->GetDecayTable();
00232         G4DecayTable *newDecayTable = new G4DecayTable();
00233         int nOrgChannels = orgDecayTable->entries();
00234 
00235         // save orgBR because we will be changing the BR
00236         std::vector<double> orgBRvect;
00237         for(int i=0; i<nOrgChannels; ++i)
00238                 orgBRvect.push_back(orgDecayTable->GetDecayChannel(i)->GetBR());
00239 
00240         for(unsigned i=0; i<channel.size(); ++i) {
00241                 G4String channelName=channel[i];
00242                 // find total BR for all org channels that match channelName
00243                 double totalBR=0.0;
00244                 for(int j=0; j<nOrgChannels; ++j) {
00245                         G4VDecayChannel *p=orgDecayTable->GetDecayChannel(j);
00246                         if(isMatch(channelName,p))
00247                                 totalBR += p->GetBR();
00248                 }
00249                 if(totalBR > 0.0) {
00250                         double ratio = br[i]/totalBR;
00251                         // update channels' BR and insert into newDecayTable
00252                         for(int j=0; j<nOrgChannels; ++j) {
00253                                 G4VDecayChannel *p=orgDecayTable->
00254                                                         GetDecayChannel(j);
00255                                 if(isMatch(channelName,p)) {
00256                                         p->SetBR(p->GetBR()*ratio);
00257                                         newDecayTable->Insert(p);
00258                                 }
00259                         }
00260                         continue;
00261                 }
00262                 // Create the channel (default phase space decay -- valid for
00263                 // 2-particle decays, but probably incorrect for 3 or more
00264                 // daughters or non-zero spin). Caveat utilitor.
00265                 std::vector<G4String> daughter = 
00266                                         BLCommand::splitString(channelName,",");
00267                 int n=daughter.size();
00268                 if(n > 4) {
00269                         n = 4;
00270                         BLCommand::printError("setdecay: too many daughters - "
00271                                                 "simulation aborted.");
00272                         fatalError();
00273                 }
00274                 while(daughter.size() < 4) daughter.push_back("");
00275                 newDecayTable->Insert(new G4PhaseSpaceDecayChannel(particleName,
00276                     br[i],n,daughter[0],daughter[1],daughter[2],daughter[3]));
00277 
00278         }
00279         pd->SetDecayTable(newDecayTable);
00280 
00281         // print new and org decay tables
00282         printf("  Original Decay Channels                 New Decay Channels\n");
00283         for(int i=0; ; ++i) {
00284                 double orgBR=-1.0, newBR=-1.0;
00285                 G4String orgName="", newName="";
00286                 char orgBRstring[32]="", newBRstring[32]="";
00287                 if(i < orgDecayTable->entries()) {
00288                         orgBR = orgBRvect[i];
00289                         orgName = 
00290                             decayChannelName(orgDecayTable->GetDecayChannel(i));
00291                         sprintf(orgBRstring,"%.6f",orgBR);
00292                 }
00293                 if(i < newDecayTable->entries()) {
00294                         newBR = newDecayTable->GetDecayChannel(i)->GetBR();
00295                         newName = 
00296                             decayChannelName(newDecayTable->GetDecayChannel(i));
00297                         sprintf(newBRstring,"%.6f",newBR);
00298                 }
00299                 if(orgBR < 0.0 && newBR < 0.0) break;
00300                 printf(" %9.9s %-26.26s    %9.9s %-26.26s\n",
00301                     orgBRstring,orgName.c_str(),newBRstring,newName.c_str());
00302         }
00303         printf("\n");
00304 
00305         // deliberate memory leak: don't delete orgDecayChannel (it might delete
00306         // the G4DecayChannel-s it uses, which we re-used).
00307 }

bool SetDecayInstance::isMatch ( G4String  name,
G4VDecayChannel *  chan 
)

References BLCommand::splitString().

Referenced by callback().

00310 {
00311         std::vector<G4String> list = BLCommand::splitString(name,",");
00312         int nDaughters=chan->GetNumberOfDaughters();
00313         if(list.size() != (unsigned)nDaughters) return false;
00314         for(unsigned i=0; i<list.size(); ++i) {
00315                 bool ok=false;
00316                 for(int j=0; j<nDaughters; ++j) {
00317                         if(list[i] == chan->GetDaughterName(j)) {
00318                                 ok = true;
00319                                 break;
00320                         }
00321                 }
00322                 if(!ok) return false;
00323         }
00324         return true;
00325 }

G4String SetDecayInstance::decayChannelName ( const G4VDecayChannel *  channel  ) 

decayChannelName() returns the name of the channel.

Referenced by callback().

00328 {
00329         int n=channel->GetNumberOfDaughters();
00330         G4String name=channel->GetDaughterName(0);
00331         for(int i=1; i<n; ++i) {
00332                 name += ",";
00333                 name += channel->GetDaughterName(i);
00334         }
00335         return name;
00336 }

void SetDecayInstance::fatalError (  ) 

fatalError() arranges to abort the simulation after all callbacks have run.

References BLCallback::BLCallback(), callback(), g4bl_exit(), BLManager::getObject(), BLCommand::printError(), and BLManager::registerCallback().

Referenced by callback().

00339 {
00340         class Abort : public BLCallback {
00341         public:
00342                 Abort() : BLCallback() { }
00343                 void callback(int type) {
00344                         extern void g4bl_exit(int);
00345                         BLCommand::printError("setdecay: FATAL ERROR -- "
00346                                                 "simulation aborted.\n");
00347                         g4bl_exit(99);
00348                 }
00349         };
00350         BLManager::getObject()->registerCallback(new Abort(),0);
00351 }


Friends And Related Function Documentation

friend class BLCMDsetdecay [friend]


Member Data Documentation

G4String SetDecayInstance::particleName [private]

Referenced by callback(), and SetDecayInstance().

double SetDecayInstance::lifetime [private]

std::vector<G4String> SetDecayInstance::channel [private]

Referenced by callback(), and BLCMDsetdecay::command().

std::vector<double> SetDecayInstance::br [private]

Referenced by callback(), and BLCMDsetdecay::command().

bool SetDecayInstance::first = true [static, private]

Referenced by callback().


The documentation for this class was generated from the following file:
g4beamline