Geant4  10.00.p02
G4TrackList.cc
Go to the documentation of this file.
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 // $Id: G4TrackList.cc 65022 2012-11-12 16:43:12Z gcosmo $
27 //
28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
29 //
30 // History:
31 // -----------
32 // 10 Oct 2011 M.Karamitros created
33 //
34 // -------------------------------------------------------------------
35 
36 #include "G4TrackList.hh"
37 #include "G4IT.hh"
38 #include "G4Track.hh"
39 
40 using namespace std;
41 
42 //***********************************************************
43 // TrackList_iterator
44 G4Track*
46 { return fpNode->GetTrack(); }
47 
48 G4Track*
50 { return fpNode->GetTrack(); }
51 
52 const G4Track*
54 { return fpNode->GetTrack(); }
55 
56 const G4Track*
58 { return fpNode->GetTrack(); }
59 
60 
61 //***********************************************************
62 // TrackNodeList
63 
65  fpTrack(track),
66  fpPrevious(0),
67  fpNext(0)
68 {
69  fAttachedToList = false;
70 }
71 
73 {;}
74 
75 //***********************************************************
76 
77 G4TrackList::G4TrackList() : fBoundary()
78 {
79  fListRef = new _ListRef(this);
80  fpStart = 0;
81  fpFinish = 0;
82  fNbTracks = 0 ;
86 }
87 
88 // should not be used
89 G4TrackList::G4TrackList(const G4TrackList& /*other*/) : fBoundary()
90 {
91  // One track should not belong to two different trackLists
92 
93  fpFinish = 0;
94  fpStart = 0;
95  fNbTracks = 0;
96  fListRef = 0;
97 }
98 
100 {
101  // One track should not belong to two different trackList
102  if (this == &other) return *this; // handle self assignment
103  //assignment operator
104  return *this;
105 }
106 
108 {
109  if( fNbTracks != 0 )
110  {
111  G4TrackListNode * __stackedTrack = fpStart;
112  G4TrackListNode * __nextStackedTrack;
113 
114  // delete tracks in the stack
115  while( __stackedTrack && __stackedTrack != &(fBoundary) )
116  {
117  __nextStackedTrack = __stackedTrack->GetNext();
118  G4Track* __track = __stackedTrack->GetTrack();
119 
120  delete __stackedTrack;
121  __stackedTrack = 0;
122 
123  if(__track)
124  {
126  DeleteTrack(__track);
127  __track = 0;
129  }
130 
131  __stackedTrack = __nextStackedTrack;
132  }
133  }
134  fNbTracks = 0;
135 }
136 
137 bool G4TrackList::Holds(const G4Track* track) const
138 {
139  return (GetIT(track)->GetTrackListNode()->fListRef->fpTrackList == this) ;
140 }
141 
143 {
144  G4IT* __iTrack = GetIT(__track);
145  G4TrackListNode* __trackListNode = __iTrack->GetTrackListNode();
146 
147  if(__trackListNode != 0)
148  {
149  // Suggestion move the node to this list
150  if(__trackListNode->fAttachedToList)
151  {
152  G4ExceptionDescription exceptionDescription ;
153  exceptionDescription << "This track "<< __iTrack->GetName() ;
154  exceptionDescription << " is already attached to a TrackList ";
155  G4Exception("G4TrackList::Flag","G4TrackList001",
156  FatalErrorInArgument,exceptionDescription);
157  }
158  }
159  else
160  {
161  __trackListNode = new G4TrackListNode(__track);
162  __iTrack->SetTrackListNode(__trackListNode);
163  }
164 
165  __trackListNode->fAttachedToList = true;
166  __trackListNode->fListRef = fListRef;
167  return __trackListNode;
168 }
169 
171 {
172  G4TrackListNode* __trackListNode = Flag(__track);
173  return __trackListNode;
174 }
175 
177 {
178  if(fNbTracks == 0)
179  {
180  // DEBUG
181  // G4cout << "fNbTracks == 0" << G4endl;
182  fpStart = __toHook;
183  fpFinish = __toHook;
184  __toHook->SetNext(&fBoundary);
185  __toHook->SetPrevious(&fBoundary);
186  fBoundary.SetNext(__toHook);
187  fBoundary.SetPrevious(__toHook);
188  }
189  else if( __position == &fBoundary)
190  {
191  // DEBUG
192  // G4cout << "__position == &fBoundary" << G4endl;
193  fpFinish->SetNext( __toHook );
194  __toHook->SetPrevious( fpFinish );
195 
196  __toHook->SetNext(&fBoundary);
197  fBoundary.SetPrevious( __toHook );
198 
199  fpFinish = __toHook;
200  }
201  else if( __position == fpStart )
202  {
203  // DEBUG
204  // G4cout << "__position == fStart" << G4endl;
205  __toHook->SetPrevious( &fBoundary );
206  fBoundary.SetNext(__toHook);
207  __toHook->SetNext(fpStart);
208  fpStart->SetPrevious(__toHook);
209  fpStart = __toHook;
210  }
211  else
212  {
213  // DEBUG
214  // G4cout << "else" << G4endl;
215  G4TrackListNode* __previous = __position->GetPrevious();
216  __toHook->SetPrevious(__previous);
217  __toHook->SetNext(__position);
218  __position->SetPrevious(__toHook);
219  __previous->SetNext(__toHook);
220  }
221 
222  fNbTracks++;
223 }
224 
226 {
227  G4TrackListNode* __previous = __toUnHook->GetPrevious();
228  G4TrackListNode* __next = __toUnHook->GetNext();
229 
230  __toUnHook->SetPrevious(0);
231  __toUnHook->SetNext(0);
232 
233  if( fNbTracks == 1 )
234  {
235  fpStart = 0;
236  fpFinish = 0;
237  }
238  else
239  {
240  if(__toUnHook == fpFinish)
241  {
242  fpFinish = __previous;
243  }
244  if(__toUnHook == fpStart)
245  {
246  fpStart = __next;
247  }
248  }
249 
250  // There should be always a __next and a __previous
251  // because it is a circle link
252  __next->SetPrevious(__previous);
253  __previous->SetNext(__next);
254 
255  fNbTracks--;
256 }
257 
259 {
260  G4TrackListNode* __node = CreateNode(__track);
261  Hook(__position.fpNode, __node);
262  return iterator(__node);
263 }
264 
265 //____________________________________________________________________
266 //
267 // WITHDRAW FROM LIST
268 //____________________________________________________________________
270 {
271  if(__trackListNode -> fListRef->fpTrackList != this)
272  {
273  G4Track* track = __trackListNode->GetTrack();
274  G4ExceptionDescription exceptionDescription ;
275  exceptionDescription
276  << "The track "<< GetIT(track)->GetName()
277  << " with trackID " << track->GetTrackID()
278  << " is not correctly linked to a TrackList."
279  << G4endl
280  << "You are probably trying to withdraw this track "
281  << "from the list but it probably does not belong to "
282  << "this track list." << G4endl;
283  G4Exception("G4TrackList::CheckFlag","G4TrackList002",
284  FatalErrorInArgument,exceptionDescription);
285  }
286 }
287 
289 {
290  G4IT* __IT = GetIT(__track);
291  G4TrackListNode* __trackListNode = __IT->GetTrackListNode();
292  // TODO : complete the exception
293  if(__trackListNode == 0)
294  {
295  G4ExceptionDescription exceptionDescription ;
296  exceptionDescription << "This track "<< GetIT(__track)->GetName() ;
297  exceptionDescription << " was not connected to any trackList ";
298  G4Exception("G4TrackList::Unflag","G4TrackList003",
299  FatalErrorInArgument,exceptionDescription);
300  return 0;
301  }
302  CheckFlag(__trackListNode);
303  __trackListNode->fAttachedToList = false;
304  __trackListNode->fListRef = 0;
305  return __trackListNode;
306 }
307 
309 {
310  if( fNbTracks == 0 ) return 0;
311  G4TrackListNode * __aStackedTrack = fpFinish;
312  Unhook( __aStackedTrack );
313  Unflag( __aStackedTrack->GetTrack() );
314  return __aStackedTrack->GetTrack();
315 }
316 
318 {
319  G4TrackListNode* __node = Unflag(__track);
320  iterator __next(__node->GetNext());
321  Unhook(__node);
322  return __next;
323 }
324 
326 {
327  G4TrackListNode* __node = Unflag(__track);
328  GetIT(__track)->SetTrackListNode(0);
329  G4TrackListNode* __next = __node->GetNext();
330  Unhook(__node);
331  delete __node;
332  return __next;
333 }
334 
336 {
337  G4Step* __step = const_cast<G4Step*>(__track->GetStep());
338  if(__step)
339  {
340  if(__step->GetfSecondary()) __step->DeleteSecondaryVector();
341  delete __step;
342  }
343  delete __track;
344 }
345 
347 {
348  G4TrackListNode* __next_node = EraseTrackListNode(__track);
350  DeleteTrack(__track);
351  __track = 0;
353  iterator __next(__next_node);
354  return __next;
355 }
356 
358 {
359  this->erase(__track);
360 }
361 
364 {
365  if(fNbTracks == 0) return iterator(&fBoundary);
366 
367  while (__first != __last)
368  {
369  if(__first . fpNode)
370  __first = pop(*__first);
371  }
372  return __last;
373 }
374 
375 
378 {
379  if(fNbTracks == 0) return iterator(&fBoundary);
380 
381  while (__first != __last)
382  {
383  if(__first . fpNode)
384  __first = erase(*__first);
385  }
386  return __last;
387 }
388 
390 {
391  if(fNbTracks==0) return;
392 
393  if(__destination->fNbTracks == 0)
394  {
395  __destination->fpStart = this->fpStart ;
396  __destination->fpFinish = this->fpFinish ;
397  __destination->fNbTracks = this->fNbTracks;
398 
399  __destination->fBoundary.SetNext(fpStart);
400  __destination->fBoundary.SetPrevious(fpFinish);
401 
402  __destination->fpFinish->SetNext(&__destination->fBoundary);
403  __destination->fpStart->SetPrevious(&__destination->fBoundary);
404  }
405  else
406  {
407  this->fpStart->SetPrevious(__destination->fpFinish);
408  __destination->fpFinish->SetNext(this->fpStart);
409  __destination->fBoundary.SetPrevious(this->fpFinish);
410  this->fpFinish->SetNext(&__destination->fBoundary);
411 
412  __destination->fpFinish = this->fpFinish;
413  __destination->fNbTracks += this->fNbTracks;
414  }
415 
416  fNbTracks = 0;
417  fpStart = 0;
418  fpFinish = 0;
419  this->fBoundary.SetPrevious(&this->fBoundary);
420  this->fBoundary.SetNext(&this->fBoundary);
421 
422  fListRef->fpTrackList = __destination;
423 }
G4IT is a interface which allows the inheriting object :
Definition: G4IT.hh:82
G4Track * operator->()
Definition: G4TrackList.cc:49
G4TrackListNode is the entity actually stored by the G4TrackList.
Definition: G4TrackList.hh:72
G4TrackList_iterator iterator
Definition: G4TrackList.hh:120
bool Holds(const G4Track *) const
return an iterator that contains an empty node use for boundary checking only
Definition: G4TrackList.cc:137
G4TrackListNode * Flag(G4Track *)
Definition: G4TrackList.cc:142
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4ReferenceCountedHandle< _ListRef > fListRef
Definition: G4TrackList.hh:112
void DeleteSecondaryVector()
G4TrackListNode * EraseTrackListNode(G4Track *)
Definition: G4TrackList.cc:325
virtual const G4String & GetName() const =0
G4TrackList & operator=(const G4TrackList &right)
Definition: G4TrackList.cc:99
const G4Step * GetStep() const
void DeleteTrack(G4Track *)
Definition: G4TrackList.cc:335
G4TrackListNode * CreateNode(G4Track *)
Complexity = constant.
Definition: G4TrackList.cc:170
G4ReferenceCountedHandle< _ListRef > fListRef
Definition: G4TrackList.hh:92
G4Track * operator*()
Definition: G4TrackList.cc:45
G4TrackList_iterator enables to go through the tracks contained by a list.
Definition: G4TrackList.hh:194
G4IT * GetIT(const G4Track *track)
Definition: G4IT.cc:48
iterator pop(G4Track *)
Definition: G4TrackList.cc:317
G4TrackListNode * GetTrackListNode()
Definition: G4IT.hh:136
iterator insert(iterator, G4Track *)
Definition: G4TrackList.cc:258
void SetTrackListNode(G4TrackListNode *node)
Definition: G4IT.hh:137
void transferTo(G4TrackList *)
Complexity = linear in size between __first and __last.
Definition: G4TrackList.cc:389
G4Track * pop_back()
Definition: G4TrackList.cc:308
Definition: G4Step.hh:76
void SetNext(G4TrackListNode *node)
Definition: G4TrackList.hh:87
G4int GetTrackID() const
void SetPrevious(G4TrackListNode *node)
Definition: G4TrackList.hh:88
G4TrackListNode(G4Track *track=0)
Default constructor.
Definition: G4TrackList.cc:64
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4TrackListNode * fpFinish
Definition: G4TrackList.hh:111
G4TrackListNode * GetPrevious()
Definition: G4TrackList.hh:79
G4TrackVector * GetfSecondary()
void CheckFlag(G4TrackListNode *)
Definition: G4TrackList.cc:269
void Unhook(G4TrackListNode *)
Definition: G4TrackList.cc:225
iterator erase(G4Track *)
Definition: G4TrackList.cc:346
G4int fNbTracks
Definition: G4TrackList.hh:109
void Hook(G4TrackListNode *, G4TrackListNode *)
Definition: G4TrackList.cc:176
#define G4endl
Definition: G4ios.hh:61
G4TrackList is used by G4ITStepManager to save G4IT tracks only.
Definition: G4TrackList.hh:106
G4TrackList * fpTrackList
Definition: G4TrackList.hh:62
G4TrackListNode fBoundary
Definition: G4TrackList.hh:114
void remove(G4Track *)
Definition: G4TrackList.cc:357
G4TrackListNode * fpStart
Definition: G4TrackList.hh:110
G4Track * GetTrack()
Definition: G4TrackList.hh:77
G4TrackListNode * GetNext()
Definition: G4TrackList.hh:78
Comments :
Definition: G4TrackList.hh:55
G4TrackListNode * Unflag(G4Track *)
Definition: G4TrackList.cc:288
~G4TrackListNode()
Default destructor.
Definition: G4TrackList.cc:72