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

Last change on this file since 816 was 816, checked in by garnier, 16 years ago

import all except CVS

File size: 11.9 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.10 2006/06/29 18:10:19 gunter Exp $
28// GEANT4 tag $Name:  $
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  urgentStack = new G4TrackStack;
45  waitingStack = new G4TrackStack;
46  postponeStack = new G4TrackStack;
47}
48
49G4StackManager::~G4StackManager()
50{
51  if(userStackingAction) delete userStackingAction;
52  delete urgentStack;
53  delete waitingStack;
54  delete postponeStack;
55  delete theMessenger;
56  if(numberOfAdditionalWaitingStacks>0) {
57    for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
58      delete additionalWaitingStacks[i];
59    }
60  }
61}
62
63const G4StackManager & G4StackManager::operator=
64(const G4StackManager &) { return *this; }
65G4int G4StackManager::operator==(const G4StackManager &) 
66const{ return false; }
67G4int G4StackManager::operator!=(const G4StackManager &) 
68const{ return true; }
69
70G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajectory)
71{
72  G4ClassificationOfNewTrack classification;
73  if(userStackingAction) 
74  { classification = userStackingAction->ClassifyNewTrack( newTrack ); }
75  else
76  { classification = DefaultClassification( newTrack ); }
77
78  if(classification==fKill)   // delete newTrack without stacking
79  {
80#ifdef G4VERBOSE
81    if( verboseLevel > 0 )
82    {
83      G4cout << "   ---> G4Track " << newTrack << " (trackID "
84         << newTrack->GetTrackID() << ", parentID "
85         << newTrack->GetParentID() << ") is not to be stored." << G4endl;
86    }
87#endif
88    delete newTrack;
89    delete newTrajectory;
90  }
91  else
92  {
93    G4StackedTrack * newStackedTrack = new G4StackedTrack( newTrack, newTrajectory );
94    switch (classification)
95    {
96      case fUrgent:
97        urgentStack->PushToStack( newStackedTrack );
98        break;
99      case fWaiting:
100        waitingStack->PushToStack( newStackedTrack );
101        break;
102      case fPostpone:
103        postponeStack->PushToStack( newStackedTrack );
104        break;
105      default:
106        G4int i = classification - 10;
107        if(i<1||i>numberOfAdditionalWaitingStacks) {
108          G4Exception("G4StackManager : invalid classification");
109        } else {
110          additionalWaitingStacks[i-1]->PushToStack( newStackedTrack );
111        }
112        break;
113    }
114  }
115
116  return GetNUrgentTrack();
117}
118
119
120G4Track * G4StackManager::PopNextTrack(G4VTrajectory**newTrajectory)
121{
122#ifdef G4VERBOSE
123  if( verboseLevel > 0 )
124  {
125    G4cout << "### pop requested out of " 
126         << GetNUrgentTrack() << " stacked tracks." << G4endl;
127  }
128#endif
129
130  while( GetNUrgentTrack() == 0 )
131  {
132#ifdef G4VERBOSE
133    if( verboseLevel > 0 ) G4cout << "### " << GetNWaitingTrack()
134                      << " waiting tracks are re-classified to" << G4endl;
135#endif
136    waitingStack->TransferTo(urgentStack);
137    if(numberOfAdditionalWaitingStacks>0) {
138      for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
139        if(i==0) {
140          additionalWaitingStacks[0]->TransferTo(waitingStack);
141        } else {
142          additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]);
143        }
144      }
145    }
146    if(userStackingAction) userStackingAction->NewStage();
147#ifdef G4VERBOSE
148    if( verboseLevel > 0 ) G4cout << "     " << GetNUrgentTrack()
149                      << " urgent tracks and " << GetNWaitingTrack()
150                      << " waiting tracks." << G4endl;
151#endif
152    if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) return 0;
153  }
154
155  G4StackedTrack * selectedStackedTrack = urgentStack->PopFromStack();
156  G4Track * selectedTrack = selectedStackedTrack->GetTrack();
157  *newTrajectory = selectedStackedTrack->GetTrajectory();
158
159#ifdef G4VERBOSE
160  if( verboseLevel > 1 )
161  {
162    G4cout << "Selected G4StackedTrack : " << selectedStackedTrack
163         << " with G4Track " << selectedStackedTrack->GetTrack()
164         << " (trackID " << selectedStackedTrack->GetTrack()->GetTrackID()
165         << ", parentID " << selectedStackedTrack->GetTrack()->GetParentID()
166         << ")" << G4endl;
167  }
168#endif
169
170  delete selectedStackedTrack;
171  return selectedTrack;
172}
173
174void G4StackManager::ReClassify()
175{
176  G4StackedTrack * aStackedTrack;
177  G4TrackStack tmpStack;
178
179  if( !userStackingAction ) return;
180  if( GetNUrgentTrack() == 0 ) return;
181
182  urgentStack->TransferTo(&tmpStack);
183  while( (aStackedTrack=tmpStack.PopFromStack()) != 0 )
184  {
185    G4ClassificationOfNewTrack classification = 
186      userStackingAction->ClassifyNewTrack( aStackedTrack->GetTrack() );
187    switch (classification)
188    {
189      case fKill:
190        delete aStackedTrack->GetTrack();
191        delete aStackedTrack->GetTrajectory();
192        delete aStackedTrack;
193        break;
194      case fUrgent:
195        urgentStack->PushToStack( aStackedTrack );
196        break;
197      case fWaiting:
198        waitingStack->PushToStack( aStackedTrack );
199        break;
200      case fPostpone:
201        postponeStack->PushToStack( aStackedTrack );
202        break;
203      default:
204        G4int i = classification - 10;
205        if(i<1||i>numberOfAdditionalWaitingStacks) {
206          G4Exception("G4StackManager : invalid classification");
207        } else {
208          additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
209        }
210        break;
211    }
212  }
213}
214
215G4int G4StackManager::PrepareNewEvent()
216{
217  if(userStackingAction) userStackingAction->PrepareNewEvent();
218
219  G4int n_passedFromPrevious = 0;
220
221  if( GetNPostponedTrack() > 0 )
222  {
223#ifdef G4VERBOSE
224    if( verboseLevel > 0 )
225    {
226      G4cout << GetNPostponedTrack() 
227           << " postponed tracked are now shifted to the stack." << G4endl;
228    }
229#endif
230
231    G4StackedTrack * aStackedTrack;
232    G4TrackStack tmpStack;
233
234    postponeStack->TransferTo(&tmpStack);
235
236    while( (aStackedTrack=tmpStack.PopFromStack()) != 0 )
237    {
238      G4Track* aTrack = aStackedTrack->GetTrack();
239      aTrack->SetParentID(-1);
240      G4ClassificationOfNewTrack classification;
241      if(userStackingAction) 
242      { classification = userStackingAction->ClassifyNewTrack( aTrack ); }
243      else
244      { classification = DefaultClassification( aTrack ); }
245
246      if(classification==fKill)
247      {
248        delete aTrack;
249        delete aStackedTrack->GetTrajectory();
250        delete aStackedTrack;
251      }
252      else
253      {
254        aTrack->SetTrackID(-(++n_passedFromPrevious));
255        switch (classification)
256        {
257          case fUrgent:
258            urgentStack->PushToStack( aStackedTrack );
259            break;
260          case fWaiting:
261            waitingStack->PushToStack( aStackedTrack );
262            break;
263          case fPostpone:
264            postponeStack->PushToStack( aStackedTrack );
265            break;
266          default:
267            G4int i = classification - 10;
268            if(i<1||i>numberOfAdditionalWaitingStacks) {
269              G4Exception("G4StackManager : invalid classification");
270            } else {
271              additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
272            }
273            break;
274        }
275      }
276    }
277  }
278
279  return n_passedFromPrevious;
280}
281
282void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd)
283{
284  if(iAdd > numberOfAdditionalWaitingStacks)
285  {
286    for(int i=numberOfAdditionalWaitingStacks;i<iAdd;i++)
287    {
288      G4TrackStack* newStack = new G4TrackStack;
289      additionalWaitingStacks.push_back(newStack);
290    }
291    numberOfAdditionalWaitingStacks = iAdd;
292  }
293  else if (iAdd < numberOfAdditionalWaitingStacks)
294  {
295    for(int i=numberOfAdditionalWaitingStacks;i>iAdd;i--)
296    {
297      delete additionalWaitingStacks[i];
298    }
299  }
300}
301
302void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
303{
304  if(origin==destination) return;
305  G4TrackStack* originStack = 0;
306  switch(origin)
307  {
308    case fUrgent:
309      originStack = urgentStack;
310      break;
311    case fWaiting:
312      originStack = waitingStack;
313      break;
314    case fPostpone:
315      originStack = postponeStack;
316      break;
317    case fKill:
318      break;
319    default:
320      int i = origin - 10;
321      if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
322      break;
323  }
324  if(!originStack) return;
325
326  if(destination==fKill)
327  {
328    G4StackedTrack * aStackedTrack;
329    while( (aStackedTrack=originStack->PopFromStack()) != 0 )
330    {
331      delete aStackedTrack->GetTrack();
332      delete aStackedTrack->GetTrajectory();
333      delete aStackedTrack;
334    }
335  } 
336  else
337  {
338    G4TrackStack* targetStack = 0;
339    switch(destination)
340    {
341      case fUrgent:
342        targetStack = urgentStack;
343        break;
344      case fWaiting:
345        targetStack = waitingStack;
346        break;
347      case fPostpone:
348        targetStack = postponeStack;
349        break;
350      default:
351        int i = origin - 10;
352        if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
353        break;
354    }
355    if(!targetStack) return;
356    originStack->TransferTo(targetStack);
357  }
358  return;
359}
360
361void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
362{
363  if(origin==destination) return;
364  G4TrackStack* originStack = 0;
365  switch(origin)
366  {
367    case fUrgent:
368      originStack = urgentStack;
369      break;
370    case fWaiting:
371      originStack = waitingStack;
372      break;
373    case fPostpone:
374      originStack = postponeStack;
375      break;
376    case fKill:
377      break;
378    default:
379      int i = origin - 10;
380      if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
381      break;
382  }
383  if(!originStack) return;
384
385  G4StackedTrack * aStackedTrack;
386  if(destination==fKill)
387  {
388    if( (aStackedTrack=originStack->PopFromStack()) != 0 )
389    {
390      delete aStackedTrack->GetTrack();
391      delete aStackedTrack->GetTrajectory();
392      delete aStackedTrack;
393    }
394  } 
395  else
396  {
397    G4TrackStack* targetStack = 0;
398    switch(destination)
399    {
400      case fUrgent:
401        targetStack = urgentStack;
402        break;
403      case fWaiting:
404        targetStack = waitingStack;
405        break;
406      case fPostpone:
407        targetStack = postponeStack;
408        break;
409      default:
410        int i = origin - 10;
411        if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
412        break;
413    }
414    if(!targetStack) return;
415    if( (aStackedTrack=originStack->PopFromStack()) != 0 )
416    {
417      targetStack->PushToStack(aStackedTrack);
418    }
419  }
420  return;
421}
422
423
424
425
426
Note: See TracBrowser for help on using the repository browser.