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.

00074                                                  : BLCallback(), channel(), br()
00075                 { 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().

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

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

References BLCommand::splitString().

Referenced by callback().

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

G4String SetDecayInstance::decayChannelName ( const G4VDecayChannel *  channel  ) 

decayChannelName() returns the name of the channel.

Referenced by callback().

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

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().

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


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