source: trunk/source/event/src/G4StackManager.cc @ 1249

Last change on this file since 1249 was 1228, checked in by garnier, 14 years ago

update geant4.9.3 tag

File size: 12.6 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4StackManager.cc,v 1.14 2009/09/16 23:10:46 asaim Exp $
28// GEANT4 tag $Name: geant4-09-03 $
29//
30//
31//  Last Modification : 09/Dec/96 M.Asai
32//
33
34#include "G4StackManager.hh"
35#include "G4StackingMessenger.hh"
36#include "G4VTrajectory.hh"
37#include "evmandefs.hh"
38#include "G4ios.hh"
39
40G4StackManager::G4StackManager()
41:userStackingAction(0),verboseLevel(0),numberOfAdditionalWaitingStacks(0)
42{
43  theMessenger = new G4StackingMessenger(this);
44#ifdef G4_USESMARTSTACK
45  urgentStack = new G4SmartTrackStack;
46  G4cout<<"+++ G4StackManager uses G4SmartTrackStack. +++"<<G4endl;
47#else
48  urgentStack = new G4TrackStack;
49//  G4cout<<"+++ G4StackManager uses ordinary G4TrackStack. +++"<<G4endl;
50#endif
51  waitingStack = new G4TrackStack;
52  postponeStack = new G4TrackStack;
53}
54
55G4StackManager::~G4StackManager()
56{
57  if(userStackingAction) delete userStackingAction;
58
59  if(verboseLevel>0)
60  {
61    G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl;
62    G4cout << " Maximum number of tracks in the urgent stack : " << urgentStack->GetMaxNTrack() << G4endl;
63    G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl;
64  }
65  delete urgentStack;
66  delete waitingStack;
67  delete postponeStack;
68  delete theMessenger;
69  if(numberOfAdditionalWaitingStacks>0) {
70    for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
71      delete additionalWaitingStacks[i];
72    }
73  }
74}
75
76const G4StackManager & G4StackManager::operator=
77(const G4StackManager &) { return *this; }
78G4int G4StackManager::operator==(const G4StackManager &) 
79const{ return false; }
80G4int G4StackManager::operator!=(const G4StackManager &) 
81const{ return true; }
82
83G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajectory)
84{
85  G4ClassificationOfNewTrack classification;
86  if(userStackingAction) 
87  { classification = userStackingAction->ClassifyNewTrack( newTrack ); }
88  else
89  { classification = DefaultClassification( newTrack ); }
90
91  if(classification==fKill)   // delete newTrack without stacking
92  {
93#ifdef G4VERBOSE
94    if( verboseLevel > 1 )
95    {
96      G4cout << "   ---> G4Track " << newTrack << " (trackID "
97         << newTrack->GetTrackID() << ", parentID "
98         << newTrack->GetParentID() << ") is not to be stored." << G4endl;
99    }
100#endif
101    delete newTrack;
102    delete newTrajectory;
103  }
104  else
105  {
106    G4StackedTrack * newStackedTrack = new G4StackedTrack( newTrack, newTrajectory );
107    switch (classification)
108    {
109      case fUrgent:
110        urgentStack->PushToStack( newStackedTrack );
111        break;
112      case fWaiting:
113        waitingStack->PushToStack( newStackedTrack );
114        break;
115      case fPostpone:
116        postponeStack->PushToStack( newStackedTrack );
117        break;
118      default:
119        G4int i = classification - 10;
120        if(i<1||i>numberOfAdditionalWaitingStacks) {
121          G4Exception("G4StackManager : invalid classification");
122        } else {
123          additionalWaitingStacks[i-1]->PushToStack( newStackedTrack );
124        }
125        break;
126    }
127  }
128
129  return GetNUrgentTrack();
130}
131
132
133G4Track * G4StackManager::PopNextTrack(G4VTrajectory**newTrajectory)
134{
135#ifdef G4VERBOSE
136  if( verboseLevel > 1 )
137  {
138    G4cout << "### pop requested out of " 
139         << GetNUrgentTrack() << " stacked tracks." << G4endl;
140  }
141#endif
142
143  while( GetNUrgentTrack() == 0 )
144  {
145#ifdef G4VERBOSE
146    if( verboseLevel > 1 ) G4cout << "### " << GetNWaitingTrack()
147                      << " waiting tracks are re-classified to" << G4endl;
148#endif
149    waitingStack->TransferTo(urgentStack);
150    if(numberOfAdditionalWaitingStacks>0) {
151      for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
152        if(i==0) {
153          additionalWaitingStacks[0]->TransferTo(waitingStack);
154        } else {
155          additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]);
156        }
157      }
158    }
159    if(userStackingAction) userStackingAction->NewStage();
160#ifdef G4VERBOSE
161    if( verboseLevel > 1 ) G4cout << "     " << GetNUrgentTrack()
162                      << " urgent tracks and " << GetNWaitingTrack()
163                      << " waiting tracks." << G4endl;
164#endif
165    if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) return 0;
166  }
167
168  G4StackedTrack * selectedStackedTrack = urgentStack->PopFromStack();
169  G4Track * selectedTrack = selectedStackedTrack->GetTrack();
170  *newTrajectory = selectedStackedTrack->GetTrajectory();
171
172#ifdef G4VERBOSE
173  if( verboseLevel > 2 )
174  {
175    G4cout << "Selected G4StackedTrack : " << selectedStackedTrack
176         << " with G4Track " << selectedStackedTrack->GetTrack()
177         << " (trackID " << selectedStackedTrack->GetTrack()->GetTrackID()
178         << ", parentID " << selectedStackedTrack->GetTrack()->GetParentID()
179         << ")" << G4endl;
180  }
181#endif
182
183  delete selectedStackedTrack;
184  return selectedTrack;
185}
186
187void G4StackManager::ReClassify()
188{
189  G4StackedTrack * aStackedTrack;
190  G4TrackStack tmpStack;
191
192  if( !userStackingAction ) return;
193  if( GetNUrgentTrack() == 0 ) return;
194
195  urgentStack->TransferTo(&tmpStack);
196  while( (aStackedTrack=tmpStack.PopFromStack()) != 0 )
197  {
198    G4ClassificationOfNewTrack classification = 
199      userStackingAction->ClassifyNewTrack( aStackedTrack->GetTrack() );
200    switch (classification)
201    {
202      case fKill:
203        delete aStackedTrack->GetTrack();
204        delete aStackedTrack->GetTrajectory();
205        delete aStackedTrack;
206        break;
207      case fUrgent:
208        urgentStack->PushToStack( aStackedTrack );
209        break;
210      case fWaiting:
211        waitingStack->PushToStack( aStackedTrack );
212        break;
213      case fPostpone:
214        postponeStack->PushToStack( aStackedTrack );
215        break;
216      default:
217        G4int i = classification - 10;
218        if(i<1||i>numberOfAdditionalWaitingStacks) {
219          G4Exception("G4StackManager : invalid classification");
220        } else {
221          additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
222        }
223        break;
224    }
225  }
226}
227
228G4int G4StackManager::PrepareNewEvent()
229{
230  if(userStackingAction) userStackingAction->PrepareNewEvent();
231
232  G4int n_passedFromPrevious = 0;
233
234  if( GetNPostponedTrack() > 0 )
235  {
236#ifdef G4VERBOSE
237    if( verboseLevel > 1 )
238    {
239      G4cout << GetNPostponedTrack() 
240           << " postponed tracked are now shifted to the stack." << G4endl;
241    }
242#endif
243
244    G4StackedTrack * aStackedTrack;
245    G4TrackStack tmpStack;
246
247    postponeStack->TransferTo(&tmpStack);
248
249    while( (aStackedTrack=tmpStack.PopFromStack()) != 0 )
250    {
251      G4Track* aTrack = aStackedTrack->GetTrack();
252      aTrack->SetParentID(-1);
253      G4ClassificationOfNewTrack classification;
254      if(userStackingAction) 
255      { classification = userStackingAction->ClassifyNewTrack( aTrack ); }
256      else
257      { classification = DefaultClassification( aTrack ); }
258
259      if(classification==fKill)
260      {
261        delete aTrack;
262        delete aStackedTrack->GetTrajectory();
263        delete aStackedTrack;
264      }
265      else
266      {
267        aTrack->SetTrackID(-(++n_passedFromPrevious));
268        switch (classification)
269        {
270          case fUrgent:
271            urgentStack->PushToStack( aStackedTrack );
272            break;
273          case fWaiting:
274            waitingStack->PushToStack( aStackedTrack );
275            break;
276          case fPostpone:
277            postponeStack->PushToStack( aStackedTrack );
278            break;
279          default:
280            G4int i = classification - 10;
281            if(i<1||i>numberOfAdditionalWaitingStacks) {
282              G4Exception("G4StackManager : invalid classification");
283            } else {
284              additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
285            }
286            break;
287        }
288      }
289    }
290  }
291
292  return n_passedFromPrevious;
293}
294
295void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd)
296{
297  if(iAdd > numberOfAdditionalWaitingStacks)
298  {
299    for(int i=numberOfAdditionalWaitingStacks;i<iAdd;i++)
300    {
301      G4TrackStack* newStack = new G4TrackStack;
302      additionalWaitingStacks.push_back(newStack);
303    }
304    numberOfAdditionalWaitingStacks = iAdd;
305  }
306  else if (iAdd < numberOfAdditionalWaitingStacks)
307  {
308    for(int i=numberOfAdditionalWaitingStacks;i>iAdd;i--)
309    {
310      delete additionalWaitingStacks[i];
311    }
312  }
313}
314
315void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
316{
317  if(origin==destination) return;
318  if(origin==fKill) return;
319  G4TrackStack* originStack = 0;
320  switch(origin)
321  {
322    case fUrgent:
323      originStack = 0;
324      break;
325    case fWaiting:
326      originStack = waitingStack;
327      break;
328    case fPostpone:
329      originStack = postponeStack;
330      break;
331    default:
332      int i = origin - 10;
333      if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
334      break;
335  }
336
337  if(destination==fKill)
338  {
339    if(originStack)
340    { originStack->clear(); }
341    else
342    { urgentStack->clear(); }
343  } 
344  else
345  {
346    G4TrackStack* targetStack = 0;
347    switch(destination)
348    {
349      case fUrgent:
350        targetStack = 0;
351        break;
352      case fWaiting:
353        targetStack = waitingStack;
354        break;
355      case fPostpone:
356        targetStack = postponeStack;
357        break;
358      default:
359        int i = origin - 10;
360        if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
361        break;
362    }
363    if(originStack)
364    {
365      if(targetStack)
366      { originStack->TransferTo(targetStack); }
367      else
368      { originStack->TransferTo(urgentStack); }
369    }
370    else
371    { urgentStack->TransferTo(targetStack); }
372  }
373  return;
374}
375
376void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
377{
378  if(origin==destination) return;
379  if(origin==fKill) return;
380  G4TrackStack* originStack = 0;
381  switch(origin)
382  {
383    case fUrgent:
384      originStack = 0;
385      break;
386    case fWaiting:
387      originStack = waitingStack;
388      break;
389    case fPostpone:
390      originStack = postponeStack;
391      break;
392    default:
393      int i = origin - 10;
394      if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
395      break;
396  }
397
398  G4StackedTrack * aStackedTrack = 0;
399  if(destination==fKill)
400  {
401    if(originStack)
402    { aStackedTrack = originStack->PopFromStack(); }
403    else
404    { aStackedTrack = urgentStack->PopFromStack(); }
405    if(aStackedTrack)
406    {
407      delete aStackedTrack->GetTrack();
408      delete aStackedTrack->GetTrajectory();
409      delete aStackedTrack;
410    }
411  } 
412  else
413  {
414    G4TrackStack* targetStack = 0;
415    switch(destination)
416    {
417      case fUrgent:
418        targetStack = 0;
419        break;
420      case fWaiting:
421        targetStack = waitingStack;
422        break;
423      case fPostpone:
424        targetStack = postponeStack;
425        break;
426      default:
427        int i = origin - 10;
428        if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
429        break;
430    }
431    if(originStack)
432    { aStackedTrack = originStack->PopFromStack(); }
433    else
434    { aStackedTrack = urgentStack->PopFromStack(); }
435    if(targetStack)
436    { targetStack->PushToStack(aStackedTrack); }
437    else
438    { urgentStack->PushToStack(aStackedTrack); }
439  }
440  return;
441}
442
443
444
445
446
Note: See TracBrowser for help on using the repository browser.