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.

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


Member Function Documentation

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

callack() from BLCallback.

Reimplemented from BLCallback.

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

Referenced by fatalError().

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

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

References BLCommand::splitString().

Referenced by callback().

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

G4String SetDecayInstance::decayChannelName ( const G4VDecayChannel *  channel  ) 

decayChannelName() returns the name of the channel.

Referenced by callback().

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

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

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


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