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 // 00027 // $Id$ 00028 // 00029 00030 #include "G4SmartTrackStack.hh" 00031 #include "G4VTrajectory.hh" 00032 #include "G4Track.hh" 00033 00034 void G4SmartTrackStack::dumpStatistics() 00035 { 00036 // Print to stderr so that we can split stats output from normal 00037 // output of Geant4 which is typically being printed to stdout 00038 for (int i = 0; i < nTurn; i++) { 00039 G4cerr << stacks[i]->GetNTrack() << " "; 00040 G4cerr << stacks[i]->getTotalEnergy() << " "; 00041 } 00042 G4cerr << G4endl; 00043 } 00044 00045 G4SmartTrackStack::G4SmartTrackStack() 00046 :fTurn(0), nTurn(5), maxNTracks(0), nTracks(0) 00047 { 00048 for(int i=0;i<nTurn;i++) 00049 { 00050 stacks[i] = new G4TrackStack(5000); 00051 energies[i] = 0.; 00052 } 00053 } 00054 00055 G4SmartTrackStack::~G4SmartTrackStack() 00056 { 00057 for (int i = 0; i < nTurn; i++) { 00058 delete stacks[i]; 00059 } 00060 } 00061 00062 const G4SmartTrackStack & 00063 G4SmartTrackStack::operator=(const G4SmartTrackStack &) { 00064 return *this; 00065 } 00066 00067 int G4SmartTrackStack::operator==(const G4SmartTrackStack &right) const { 00068 return (this==&right); 00069 } 00070 00071 int G4SmartTrackStack::operator!=(const G4SmartTrackStack &right) const { 00072 return (this!=&right); 00073 } 00074 00075 void G4SmartTrackStack::TransferTo(G4TrackStack* aStack) 00076 { 00077 for (int i = 0; i < nTurn; i++) { 00078 stacks[i]->TransferTo(aStack); 00079 } 00080 nTracks = 0; 00081 } 00082 00083 G4StackedTrack G4SmartTrackStack::PopFromStack() 00084 { 00085 G4StackedTrack aStackedTrack; 00086 00087 if (nTracks) { 00088 while (true) { 00089 if (stacks[fTurn]->GetNTrack()) { 00090 aStackedTrack = stacks[fTurn]->PopFromStack(); 00091 energies[fTurn] -= aStackedTrack.GetTrack()->GetDynamicParticle()->GetTotalEnergy(); 00092 nTracks--; 00093 break; 00094 } else { 00095 fTurn = (fTurn+1) % nTurn; 00096 } 00097 } 00098 } 00099 00100 // dumpStatistics(); 00101 return aStackedTrack; 00102 } 00103 00104 enum { 00105 electronCode = 11, positronCode = -11, gammaCode = 22, neutronCode = 2112 00106 }; 00107 00108 void G4SmartTrackStack::PushToStack( const G4StackedTrack& aStackedTrack ) 00109 { 00110 00111 G4int iDest = 0; 00112 if (aStackedTrack.GetTrack()->GetParentID()) { 00113 G4int code = aStackedTrack.GetTrack()->GetDynamicParticle()->GetPDGcode(); 00114 if (code == electronCode) 00115 iDest = 2; 00116 else if (code == gammaCode) 00117 iDest = 3; 00118 else if (code == positronCode) 00119 iDest = 4; 00120 else if (code == neutronCode) 00121 iDest = 1; 00122 } else { 00123 // We have a primary track, which should go first. 00124 fTurn = 0; // reseting the turn 00125 } 00126 stacks[iDest]->PushToStack(aStackedTrack); 00127 energies[iDest] += aStackedTrack.GetTrack()->GetDynamicParticle()->GetTotalEnergy(); 00128 nTracks++; 00129 00130 G4int dy1 = stacks[iDest]->GetNTrack() - stacks[iDest]->GetSafetyValve1(); 00131 G4int dy2 = stacks[fTurn]->GetNTrack() - stacks[fTurn]->GetSafetyValve2(); 00132 00133 if (dy1 > 0 || dy1 > dy2 || 00134 (iDest == 2 && 00135 stacks[iDest]->GetNTrack() < 50 && energies[iDest] < energies[fTurn])) { 00136 fTurn = iDest; 00137 } 00138 00139 if (nTracks > maxNTracks) maxNTracks = nTracks; 00140 } 00141 00142 void G4SmartTrackStack::clear() 00143 { 00144 for (int i = 0; i < nTurn; i++) { 00145 stacks[i]->clear(); 00146 energies[i] = 0.0; 00147 fTurn = 0; 00148 } 00149 nTracks = 0; 00150 } 00151 00152 void G4SmartTrackStack::clearAndDestroy() 00153 { 00154 for (int i = 0; i < nTurn; i++) { 00155 stacks[i]->clearAndDestroy(); 00156 energies[i] = 0.0; 00157 fTurn = 0; 00158 } 00159 nTracks = 0; 00160 }