00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00046 #else
00047 urgentStack = new G4TrackStack(5000);
00048
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)
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();
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