G4StackManager.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 // $Id$
00028 //
00029 //
00030 //  Last Modification : 09/Dec/96 M.Asai
00031 //
00032 
00033 #include "G4StackManager.hh"
00034 #include "G4StackingMessenger.hh"
00035 #include "G4VTrajectory.hh"
00036 #include "evmandefs.hh"
00037 #include "G4ios.hh"
00038 
00039 G4StackManager::G4StackManager()
00040 :userStackingAction(0),verboseLevel(0),numberOfAdditionalWaitingStacks(0)
00041 {
00042   theMessenger = new G4StackingMessenger(this);
00043 #ifdef G4_USESMARTSTACK
00044   urgentStack = new G4SmartTrackStack;
00045  // G4cout<<"+++ G4StackManager uses G4SmartTrackStack. +++"<<G4endl;
00046 #else
00047   urgentStack = new G4TrackStack(5000);
00048 //  G4cout<<"+++ G4StackManager uses ordinary G4TrackStack. +++"<<G4endl;
00049 #endif
00050   waitingStack = new G4TrackStack(1000);
00051   postponeStack = new G4TrackStack(1000);
00052 }
00053 
00054 G4StackManager::~G4StackManager()
00055 {
00056   if(userStackingAction) delete userStackingAction;
00057 
00058   if(verboseLevel>0)
00059   {
00060     G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl;
00061     G4cout << " Maximum number of tracks in the urgent stack : " << urgentStack->GetMaxNTrack() << G4endl;
00062     G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl;
00063   }
00064   delete urgentStack;
00065   delete waitingStack;
00066   delete postponeStack;
00067   delete theMessenger;
00068   if(numberOfAdditionalWaitingStacks>0) {
00069     for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
00070       delete additionalWaitingStacks[i];
00071     }
00072   }
00073 }
00074 
00075 const G4StackManager & G4StackManager::operator=
00076 (const G4StackManager &) { return *this; }
00077 G4int G4StackManager::operator==(const G4StackManager &) 
00078 const{ return false; }
00079 G4int G4StackManager::operator!=(const G4StackManager &) 
00080 const{ return true; }
00081 
00082 G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajectory)
00083 {
00084   G4ClassificationOfNewTrack classification;
00085   if(userStackingAction) 
00086   { classification = userStackingAction->ClassifyNewTrack( newTrack ); }
00087   else
00088   { classification = DefaultClassification( newTrack ); }
00089 
00090   if(classification==fKill)   // delete newTrack without stacking
00091   {
00092 #ifdef G4VERBOSE
00093     if( verboseLevel > 1 )
00094     {
00095       G4cout << "   ---> G4Track " << newTrack << " (trackID "
00096          << newTrack->GetTrackID() << ", parentID "
00097          << newTrack->GetParentID() << ") is not to be stored." << G4endl;
00098     }
00099 #endif
00100     delete newTrack;
00101     delete newTrajectory;
00102   }
00103   else
00104   {
00105     G4StackedTrack newStackedTrack( newTrack, newTrajectory );
00106     switch (classification)
00107     {
00108       case fUrgent:
00109         urgentStack->PushToStack( newStackedTrack );
00110         break;
00111       case fWaiting:
00112         waitingStack->PushToStack( newStackedTrack );
00113         break;
00114       case fPostpone:
00115         postponeStack->PushToStack( newStackedTrack );
00116         break;
00117       default:
00118         G4int i = classification - 10;
00119         if(i<1||i>numberOfAdditionalWaitingStacks) {
00120           G4ExceptionDescription ED;
00121           ED << "invalid classification " << classification << G4endl;
00122           G4Exception("G4StackManager::PushOneTrack","Event0051",
00123           FatalException,ED);
00124         } else {
00125           additionalWaitingStacks[i-1]->PushToStack( newStackedTrack );
00126         }
00127         break;
00128     }
00129   }
00130 
00131   return GetNUrgentTrack();
00132 }
00133 
00134 
00135 G4Track * G4StackManager::PopNextTrack(G4VTrajectory**newTrajectory)
00136 {
00137 #ifdef G4VERBOSE
00138   if( verboseLevel > 1 )
00139   {
00140     G4cout << "### pop requested out of " 
00141          << GetNUrgentTrack() << " stacked tracks." << G4endl;
00142   }
00143 #endif
00144 
00145   while( GetNUrgentTrack() == 0 )
00146   {
00147 #ifdef G4VERBOSE
00148     if( verboseLevel > 1 ) G4cout << "### " << GetNWaitingTrack()
00149                       << " waiting tracks are re-classified to" << G4endl;
00150 #endif
00151     waitingStack->TransferTo(urgentStack);
00152     if(numberOfAdditionalWaitingStacks>0) {
00153       for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
00154         if(i==0) {
00155           additionalWaitingStacks[0]->TransferTo(waitingStack);
00156         } else {
00157           additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]);
00158         }
00159       }
00160     }
00161     if(userStackingAction) userStackingAction->NewStage();
00162 #ifdef G4VERBOSE
00163     if( verboseLevel > 1 ) G4cout << "     " << GetNUrgentTrack()
00164                       << " urgent tracks and " << GetNWaitingTrack()
00165                       << " waiting tracks." << G4endl;
00166 #endif
00167     if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) return 0;
00168   }
00169 
00170   G4StackedTrack selectedStackedTrack = urgentStack->PopFromStack();
00171   G4Track * selectedTrack = selectedStackedTrack.GetTrack();
00172   *newTrajectory = selectedStackedTrack.GetTrajectory();
00173 
00174 #ifdef G4VERBOSE
00175   if( verboseLevel > 2 )
00176   {
00177     G4cout << "Selected G4StackedTrack : " << &selectedStackedTrack
00178            << " with G4Track " << selectedStackedTrack.GetTrack()
00179            << " (trackID " << selectedStackedTrack.GetTrack()->GetTrackID()
00180            << ", parentID " << selectedStackedTrack.GetTrack()->GetParentID()
00181            << ")" << G4endl;
00182   }
00183 #endif
00184 
00185   return selectedTrack;
00186 }
00187 
00188 void G4StackManager::ReClassify()
00189 {
00190   G4StackedTrack aStackedTrack;
00191   G4TrackStack tmpStack;
00192   
00193   if( !userStackingAction ) return;
00194   if( GetNUrgentTrack() == 0 ) return;
00195   
00196   urgentStack->TransferTo(&tmpStack);
00197   while( tmpStack.GetNTrack() > 0 )
00198   {
00199     aStackedTrack=tmpStack.PopFromStack();
00200     G4ClassificationOfNewTrack classification =
00201     userStackingAction->ClassifyNewTrack( aStackedTrack.GetTrack() );
00202     switch (classification)
00203     {
00204       case fKill:
00205         delete aStackedTrack.GetTrack();
00206         delete aStackedTrack.GetTrajectory();
00207         break;
00208       case fUrgent:
00209         urgentStack->PushToStack( aStackedTrack );
00210         break;
00211       case fWaiting:
00212         waitingStack->PushToStack( aStackedTrack );
00213         break;
00214       case fPostpone:
00215         postponeStack->PushToStack( aStackedTrack );
00216         break;
00217       default:
00218         G4int i = classification - 10;
00219         if(i<1||i>numberOfAdditionalWaitingStacks) {
00220           G4ExceptionDescription ED;
00221           ED << "invalid classification " << classification << G4endl;
00222           G4Exception("G4StackManager::ReClassify","Event0052",
00223                       FatalException,ED);
00224         } else {
00225           additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
00226         }
00227         break;
00228     }
00229   }
00230 }
00231 
00232 G4int G4StackManager::PrepareNewEvent()
00233 {
00234   if(userStackingAction) userStackingAction->PrepareNewEvent();
00235   
00236   urgentStack->clearAndDestroy(); // Set the urgentStack in a defined state. Not doing it would affect reproducibility.
00237   
00238   G4int n_passedFromPrevious = 0;
00239   
00240   if( GetNPostponedTrack() > 0 )
00241   {
00242 #ifdef G4VERBOSE
00243     if( verboseLevel > 1 )
00244     {
00245       G4cout << GetNPostponedTrack()
00246              << " postponed tracked are now shifted to the stack." << G4endl;
00247     }
00248 #endif
00249     
00250     G4StackedTrack aStackedTrack;
00251     G4TrackStack   tmpStack;
00252     
00253     postponeStack->TransferTo(&tmpStack);
00254     
00255     while( tmpStack.GetNTrack() > 0 )
00256     {
00257       aStackedTrack=tmpStack.PopFromStack();
00258       G4Track* aTrack = aStackedTrack.GetTrack();
00259       aTrack->SetParentID(-1);
00260       G4ClassificationOfNewTrack classification;
00261       if(userStackingAction)
00262       { classification = userStackingAction->ClassifyNewTrack( aTrack ); }
00263       else
00264       { classification = DefaultClassification( aTrack ); }
00265       
00266       if(classification==fKill)
00267       {
00268         delete aTrack;
00269         delete aStackedTrack.GetTrajectory();
00270       }
00271       else
00272       {
00273         aTrack->SetTrackID(-(++n_passedFromPrevious));
00274         switch (classification)
00275         {
00276           case fUrgent:
00277             urgentStack->PushToStack( aStackedTrack );
00278             break;
00279           case fWaiting:
00280             waitingStack->PushToStack( aStackedTrack );
00281             break;
00282           case fPostpone:
00283             postponeStack->PushToStack( aStackedTrack );
00284             break;
00285           default:
00286             G4int i = classification - 10;
00287             if(i<1||i>numberOfAdditionalWaitingStacks) {
00288               G4ExceptionDescription ED;
00289               ED << "invalid classification " << classification << G4endl;
00290               G4Exception("G4StackManager::PrepareNewEvent","Event0053",
00291                           FatalException,ED);
00292             } else {
00293               additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
00294             }
00295             break;
00296         }
00297       }
00298     }
00299   }
00300   
00301   return n_passedFromPrevious;
00302 }
00303 
00304 void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd)
00305 {
00306   if(iAdd > numberOfAdditionalWaitingStacks)
00307   {
00308     for(int i=numberOfAdditionalWaitingStacks;i<iAdd;i++)
00309     {
00310       G4TrackStack* newStack = new G4TrackStack;
00311       additionalWaitingStacks.push_back(newStack);
00312     }
00313     numberOfAdditionalWaitingStacks = iAdd;
00314   }
00315   else if (iAdd < numberOfAdditionalWaitingStacks)
00316   {
00317     for(int i=numberOfAdditionalWaitingStacks;i>iAdd;i--)
00318     {
00319       delete additionalWaitingStacks[i];
00320     }
00321   }
00322 }
00323 
00324 void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
00325 {
00326   if(origin==destination) return;
00327   if(origin==fKill) return;
00328   G4TrackStack* originStack = 0;
00329   switch(origin)
00330   {
00331     case fUrgent:
00332       originStack = 0;
00333       break;
00334     case fWaiting:
00335       originStack = waitingStack;
00336       break;
00337     case fPostpone:
00338       originStack = postponeStack;
00339       break;
00340     default:
00341       int i = origin - 10;
00342       if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
00343       break;
00344   }
00345   
00346   if(destination==fKill)
00347   {
00348     if(originStack)
00349     { originStack->clearAndDestroy(); }
00350     else
00351     { urgentStack->clearAndDestroy(); }
00352   }
00353   else
00354   {
00355     G4TrackStack* targetStack = 0;
00356     switch(destination)
00357     {
00358       case fUrgent:
00359         targetStack = 0;
00360         break;
00361       case fWaiting:
00362         targetStack = waitingStack;
00363         break;
00364       case fPostpone:
00365         targetStack = postponeStack;
00366         break;
00367       default:
00368         int i = destination - 10;
00369         if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
00370         break;
00371     }
00372     if(originStack)
00373     {
00374       if(targetStack)
00375       { originStack->TransferTo(targetStack); }
00376       else
00377       { originStack->TransferTo(urgentStack); }
00378     }
00379     else
00380     { urgentStack->TransferTo(targetStack); }
00381   }
00382   return;
00383 }
00384 
00385 void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
00386 {
00387   if(origin==destination) return;
00388   if(origin==fKill) return;
00389   G4TrackStack* originStack = 0;
00390   switch(origin)
00391   {
00392     case fUrgent:
00393       originStack = 0;
00394       break;
00395     case fWaiting:
00396       originStack = waitingStack;
00397       break;
00398     case fPostpone:
00399       originStack = postponeStack;
00400       break;
00401     default:
00402       int i = origin - 10;
00403       if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
00404       break;
00405   }
00406   
00407   G4StackedTrack aStackedTrack;
00408   if(destination==fKill)
00409   {
00410     if( originStack && originStack->GetNTrack() ) {
00411       aStackedTrack = originStack->PopFromStack();
00412       delete aStackedTrack.GetTrack();
00413       delete aStackedTrack.GetTrajectory();
00414     }
00415     else if (urgentStack->GetNTrack() ) {
00416       aStackedTrack = urgentStack->PopFromStack();
00417       delete aStackedTrack.GetTrack();
00418       delete aStackedTrack.GetTrajectory();
00419     }
00420   }
00421   else
00422   {
00423     G4TrackStack* targetStack = 0;
00424     switch(destination)
00425     {
00426       case fUrgent:
00427         targetStack = 0;
00428         break;
00429       case fWaiting:
00430         targetStack = waitingStack;
00431         break;
00432       case fPostpone:
00433         targetStack = postponeStack;
00434         break;
00435       default:
00436         int i = destination - 10;
00437         if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
00438         break;
00439     }
00440     if(originStack && originStack->GetNTrack()) {
00441       aStackedTrack = originStack->PopFromStack();
00442       if(targetStack) { targetStack->PushToStack(aStackedTrack); }
00443       else            { urgentStack->PushToStack(aStackedTrack); }
00444     }
00445     else if(urgentStack->GetNTrack()) {
00446       aStackedTrack = urgentStack->PopFromStack();
00447       if(targetStack) { targetStack->PushToStack(aStackedTrack); }
00448       else            { urgentStack->PushToStack(aStackedTrack); }
00449     }
00450   }
00451   return;
00452 }
00453 
00454 void G4StackManager::clear()
00455 {
00456   ClearUrgentStack();
00457   ClearWaitingStack();
00458   for(int i=1;i<=numberOfAdditionalWaitingStacks;i++) {ClearWaitingStack(i);}
00459 }
00460 
00461 void G4StackManager::ClearUrgentStack()
00462 {
00463   urgentStack->clearAndDestroy();
00464 }
00465 
00466 void G4StackManager::ClearWaitingStack(int i)
00467 {
00468   if(i==0) {
00469     waitingStack->clearAndDestroy();
00470   } else {
00471     if(i<=numberOfAdditionalWaitingStacks) additionalWaitingStacks[i-1]->clearAndDestroy();
00472   }
00473 }
00474 
00475 void G4StackManager::ClearPostponeStack()
00476 {
00477   postponeStack->clearAndDestroy();
00478 }
00479 
00480 G4int G4StackManager::GetNTotalTrack() const
00481 {
00482   int n = urgentStack->GetNTrack() + waitingStack->GetNTrack() + postponeStack->GetNTrack();
00483   for(int i=1;i<=numberOfAdditionalWaitingStacks;i++) {n += additionalWaitingStacks[i-1]->GetNTrack();}
00484   return n;
00485 }
00486 
00487 G4int G4StackManager::GetNUrgentTrack() const
00488 {
00489   return urgentStack->GetNTrack();
00490 }
00491 
00492 G4int G4StackManager::GetNWaitingTrack(int i) const
00493 {
00494   if(i==0) { return waitingStack->GetNTrack(); }
00495   else {
00496     if(i<=numberOfAdditionalWaitingStacks) { return additionalWaitingStacks[i-1]->GetNTrack();}
00497   }
00498   return 0;
00499 }
00500 
00501 G4int G4StackManager::GetNPostponedTrack() const
00502 {
00503   return postponeStack->GetNTrack();
00504 }
00505 
00506 void G4StackManager::SetVerboseLevel( G4int const value )
00507 {
00508   verboseLevel = value;
00509 }
00510 
00511 void G4StackManager::SetUserStackingAction(G4UserStackingAction* value)
00512 {
00513         userStackingAction = value;
00514   if(userStackingAction) userStackingAction->SetStackManager(this);
00515 }
00516 
00517 G4ClassificationOfNewTrack G4StackManager::DefaultClassification(G4Track *aTrack)
00518 {
00519   G4ClassificationOfNewTrack classification = fUrgent;
00520   if( aTrack->GetTrackStatus() == fPostponeToNextEvent )
00521   { classification = fPostpone; }
00522   return classification;
00523 }
00524 
00525 
00526 
00527 

Generated on Mon May 27 17:49:53 2013 for Geant4 by  doxygen 1.4.7