G4TrackList.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 // $Id: G4TrackList.cc 65022 2012-11-12 16:43:12Z gcosmo $
00027 //
00028 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
00029 //
00030 // History:
00031 // -----------
00032 // 10 Oct 2011 M.Karamitros created
00033 //
00034 // -------------------------------------------------------------------
00035 
00036 #include "G4TrackList.hh"
00037 #include "G4IT.hh"
00038 #include "G4Track.hh"
00039 
00040 using namespace std;
00041 
00042 //***********************************************************
00043 // TrackList_iterator
00044 G4Track*
00045 G4TrackList_iterator::operator*()
00046 { return fpNode->GetTrack(); }
00047 
00048 G4Track*
00049 G4TrackList_iterator::operator->()
00050 { return fpNode->GetTrack(); }
00051 
00052 const G4Track*
00053 G4TrackList_iterator::operator*() const
00054 { return fpNode->GetTrack(); }
00055 
00056 const G4Track*
00057 G4TrackList_iterator::operator->() const
00058 { return fpNode->GetTrack(); }
00059 
00060 
00061 //***********************************************************
00062 // TrackNodeList
00063 
00064 G4TrackListNode::G4TrackListNode(G4Track* track) :
00065     fpTrack(track),
00066     fpPrevious(0),
00067     fpNext(0)
00068 {
00069     fAttachedToList = false;
00070 }
00071 
00072 G4TrackListNode::~G4TrackListNode()
00073 {;}
00074 
00075 //***********************************************************
00076 
00077 G4TrackList::G4TrackList() : fBoundary()
00078 {
00079     fListRef    = new _ListRef(this);
00080     fpStart      = 0;
00081     fpFinish     = 0;
00082     fNbTracks   = 0 ;
00083     fBoundary.SetPrevious(&fBoundary);
00084     fBoundary.SetNext(&fBoundary);
00085     fBoundary.fAttachedToList = true;
00086 }
00087 
00088 // should not be used
00089 G4TrackList::G4TrackList(const G4TrackList& /*other*/) : fBoundary()
00090 {
00091     // One track should not belong to two different trackLists
00092 
00093     fpFinish = 0;
00094     fpStart = 0;
00095     fNbTracks = 0;
00096     fListRef = 0;
00097 }
00098 
00099 G4TrackList& G4TrackList::operator=(const G4TrackList& other)
00100 {
00101     // One track should not belong to two different trackList
00102     if (this == &other) return *this; // handle self assignment
00103     //assignment operator
00104     return *this;
00105 }
00106 
00107 G4TrackList::~G4TrackList()
00108 {
00109     if( fNbTracks != 0 )
00110     {
00111         G4TrackListNode * __stackedTrack = fpStart;
00112         G4TrackListNode * __nextStackedTrack;
00113 
00114         // delete tracks in the stack
00115         while(  __stackedTrack && __stackedTrack != &(fBoundary) )
00116         {
00117             __nextStackedTrack = __stackedTrack->GetNext();
00118             G4Track* __track = __stackedTrack->GetTrack();
00119 
00120             delete __stackedTrack;
00121             __stackedTrack = 0;
00122 
00123             if(__track)
00124             {
00126                 DeleteTrack(__track);
00127                 __track = 0;
00129             }
00130 
00131             __stackedTrack = __nextStackedTrack;
00132         }
00133     }
00134     fNbTracks = 0;
00135 }
00136 
00137 bool G4TrackList::Holds(const G4Track* track) const
00138 {
00139     return (GetIT(track)->GetTrackListNode()->fListRef->fpTrackList == this)  ;
00140 }
00141 
00142 G4TrackListNode* G4TrackList::Flag(G4Track* __track)
00143 {
00144     G4IT* __iTrack = GetIT(__track);
00145     G4TrackListNode* __trackListNode = __iTrack->GetTrackListNode();
00146 
00147     if(__trackListNode != 0)
00148     {
00149         // Suggestion move the node to this list
00150         if(__trackListNode->fAttachedToList)
00151         {
00152             G4ExceptionDescription exceptionDescription ;
00153             exceptionDescription << "This track "<< __iTrack->GetName() ;
00154             exceptionDescription << " is already attached to a TrackList ";
00155             G4Exception("G4TrackList::Flag","G4TrackList001",
00156                         FatalErrorInArgument,exceptionDescription);
00157          }
00158     }
00159     else
00160     {
00161         __trackListNode = new G4TrackListNode(__track);
00162         __iTrack->SetTrackListNode(__trackListNode);
00163     }
00164 
00165     __trackListNode->fAttachedToList = true;
00166     __trackListNode->fListRef = fListRef;
00167     return __trackListNode;
00168 }
00169 
00170 G4TrackListNode* G4TrackList::CreateNode(G4Track* __track)
00171 {
00172     G4TrackListNode* __trackListNode = Flag(__track);
00173     return __trackListNode;
00174 }
00175 
00176 void G4TrackList::Hook(G4TrackListNode* __position, G4TrackListNode* __toHook)
00177 {
00178     if(fNbTracks == 0)
00179     {
00180         // DEBUG
00181         //        G4cout << "fNbTracks == 0" << G4endl;
00182         fpStart = __toHook;
00183         fpFinish = __toHook;
00184         __toHook->SetNext(&fBoundary);
00185         __toHook->SetPrevious(&fBoundary);
00186         fBoundary.SetNext(__toHook);
00187         fBoundary.SetPrevious(__toHook);
00188     }
00189     else if( __position == &fBoundary)
00190     {
00191         // DEBUG
00192         //        G4cout << "__position == &fBoundary" << G4endl;
00193         fpFinish->SetNext( __toHook );
00194         __toHook->SetPrevious( fpFinish );
00195 
00196         __toHook->SetNext(&fBoundary);
00197         fBoundary.SetPrevious( __toHook );
00198 
00199         fpFinish = __toHook;
00200     }
00201     else if( __position == fpStart )
00202     {
00203         // DEBUG
00204         //        G4cout << "__position == fStart" << G4endl;
00205         __toHook->SetPrevious( &fBoundary );
00206         fBoundary.SetNext(__toHook);
00207         __toHook->SetNext(fpStart);
00208         fpStart->SetPrevious(__toHook);
00209         fpStart = __toHook;
00210     }
00211     else
00212     {
00213         // DEBUG
00214         //        G4cout << "else" << G4endl;
00215         G4TrackListNode* __previous = __position->GetPrevious();
00216         __toHook->SetPrevious(__previous);
00217         __toHook->SetNext(__position);
00218         __position->SetPrevious(__toHook);
00219         __previous->SetNext(__toHook);
00220     }
00221 
00222     fNbTracks++;
00223 }
00224 
00225 void G4TrackList::Unhook(G4TrackListNode* __toUnHook)
00226 {
00227     G4TrackListNode* __previous = __toUnHook->GetPrevious();
00228     G4TrackListNode* __next = __toUnHook->GetNext();
00229 
00230     __toUnHook->SetPrevious(0);
00231     __toUnHook->SetNext(0);
00232 
00233     if( fNbTracks == 1 )
00234     {
00235         fpStart = 0;
00236         fpFinish = 0;
00237     }
00238     else
00239     {
00240         if(__toUnHook == fpFinish)
00241         {
00242             fpFinish = __previous;
00243         }
00244         if(__toUnHook == fpStart)
00245         {
00246             fpStart = __next;
00247         }
00248     }
00249 
00250     // There should be always a __next and a __previous
00251     // because it is a circle link
00252     __next->SetPrevious(__previous);
00253     __previous->SetNext(__next);
00254 
00255     fNbTracks--;
00256 }
00257 
00258 G4TrackList::iterator G4TrackList::insert(G4TrackList::iterator __position, G4Track* __track)
00259 {
00260     G4TrackListNode* __node = CreateNode(__track);
00261     Hook(__position.fpNode, __node);
00262     return iterator(__node);
00263 }
00264 
00265 //____________________________________________________________________
00266 //
00267 //                      WITHDRAW FROM LIST
00268 //____________________________________________________________________
00269 void G4TrackList::CheckFlag(G4TrackListNode* __trackListNode)
00270 {
00271     if(__trackListNode -> fListRef->fpTrackList != this)
00272     {
00273         G4Track* track = __trackListNode->GetTrack();
00274         G4ExceptionDescription exceptionDescription ;
00275         exceptionDescription
00276                 << "The track "<< GetIT(track)->GetName()
00277                 << " with trackID " << track->GetTrackID()
00278                 << " is not correctly linked to a TrackList."
00279                 << G4endl
00280                 << "You are probably trying to withdraw this track "
00281                 << "from the list but it probably does not belong to "
00282                 << "this track list." << G4endl;
00283         G4Exception("G4TrackList::CheckFlag","G4TrackList002",
00284                     FatalErrorInArgument,exceptionDescription);
00285     }
00286 }
00287 
00288 G4TrackListNode* G4TrackList::Unflag(G4Track* __track)
00289 {
00290     G4IT* __IT = GetIT(__track);
00291     G4TrackListNode* __trackListNode = __IT->GetTrackListNode();
00292     // TODO : complete the exception
00293     if(__trackListNode == 0)
00294     {
00295         G4ExceptionDescription exceptionDescription ;
00296         exceptionDescription << "This track "<< GetIT(__track)->GetName() ;
00297         exceptionDescription << " was not connected to any trackList ";
00298         G4Exception("G4TrackList::Unflag","G4TrackList003",
00299                     FatalErrorInArgument,exceptionDescription);
00300         return 0;
00301     }
00302     CheckFlag(__trackListNode);
00303     __trackListNode->fAttachedToList = false;
00304     __trackListNode->fListRef = 0;
00305     return __trackListNode;
00306 }
00307 
00308 G4Track* G4TrackList::pop_back()
00309 {
00310     if( fNbTracks == 0 ) return 0;
00311     G4TrackListNode * __aStackedTrack = fpFinish;
00312     Unhook( __aStackedTrack );
00313     Unflag( __aStackedTrack->GetTrack() );
00314     return __aStackedTrack->GetTrack();
00315 }
00316 
00317 G4TrackList::iterator G4TrackList::pop(G4Track* __track)
00318 {
00319     G4TrackListNode* __node = Unflag(__track);
00320     iterator __next(__node->GetNext());
00321     Unhook(__node);
00322     return __next;
00323 }
00324 
00325 G4TrackListNode* G4TrackList::EraseTrackListNode(G4Track* __track)
00326 {
00327     G4TrackListNode* __node = Unflag(__track);
00328     GetIT(__track)->SetTrackListNode(0);
00329     G4TrackListNode* __next = __node->GetNext();
00330     Unhook(__node);
00331     delete __node;
00332     return __next;
00333 }
00334 
00335 void G4TrackList::DeleteTrack(G4Track* __track)
00336 {
00337     G4Step* __step = const_cast<G4Step*>(__track->GetStep());
00338     if(__step)
00339     {
00340         if(__step->GetfSecondary()) __step->DeleteSecondaryVector();
00341         delete __step;
00342     }
00343     delete __track;
00344 }
00345 
00346 G4TrackList::iterator G4TrackList::erase(G4Track* __track)
00347 {
00348     G4TrackListNode* __next_node = EraseTrackListNode(__track);
00350     DeleteTrack(__track);
00351     __track = 0;
00353     iterator __next(__next_node);
00354     return __next;
00355 }
00356 
00357 void G4TrackList::remove(G4Track* __track)
00358 {
00359     this->erase(__track);
00360 }
00361 
00362 G4TrackList::iterator
00363 G4TrackList::pop(iterator __first, iterator __last)
00364 {
00365     if(fNbTracks == 0) return iterator(&fBoundary);
00366 
00367     while (__first != __last)
00368     {
00369         if(__first . fpNode)
00370             __first = pop(*__first);
00371     }
00372     return __last;
00373 }
00374 
00375 
00376 G4TrackList::iterator
00377 G4TrackList::erase(iterator __first, iterator __last)
00378 {
00379     if(fNbTracks == 0) return iterator(&fBoundary);
00380 
00381     while (__first != __last)
00382     {
00383         if(__first . fpNode)
00384             __first = erase(*__first);
00385     }
00386     return __last;
00387 }
00388 
00389 void G4TrackList::transferTo(G4TrackList* __destination)
00390 {
00391     if(fNbTracks==0) return;
00392 
00393     if(__destination->fNbTracks == 0)
00394     {
00395         __destination->fpStart       =    this->fpStart ;
00396         __destination->fpFinish      =    this->fpFinish ;
00397         __destination->fNbTracks    =    this->fNbTracks;
00398 
00399         __destination->fBoundary.SetNext(fpStart);
00400         __destination->fBoundary.SetPrevious(fpFinish);
00401 
00402         __destination->fpFinish->SetNext(&__destination->fBoundary);
00403         __destination->fpStart->SetPrevious(&__destination->fBoundary);
00404     }
00405     else
00406     {
00407         this->fpStart->SetPrevious(__destination->fpFinish);
00408         __destination->fpFinish->SetNext(this->fpStart);
00409         __destination->fBoundary.SetPrevious(this->fpFinish);
00410         this->fpFinish->SetNext(&__destination->fBoundary);
00411 
00412         __destination->fpFinish = this->fpFinish;
00413         __destination->fNbTracks += this->fNbTracks;
00414     }
00415 
00416     fNbTracks = 0;
00417     fpStart = 0;
00418     fpFinish = 0;
00419     this->fBoundary.SetPrevious(&this->fBoundary);
00420     this->fBoundary.SetNext(&this->fBoundary);
00421 
00422     fListRef->fpTrackList = __destination;
00423 }

Generated on Mon May 27 17:50:01 2013 for Geant4 by  doxygen 1.4.7