Geant4 Cross Reference |
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 // G4Event class implementation 27 // 28 // Author: M.Asai, SLAC/JLAB 29 // -------------------------------------------------------------------- 30 31 #include "G4Event.hh" 32 #include "G4VVisManager.hh" 33 #include "G4VHitsCollection.hh" 34 #include "G4VDigiCollection.hh" 35 #include "G4ios.hh" 36 #include "G4SubEvent.hh" 37 38 #include "G4Threading.hh" 39 #include "G4AutoLock.hh" 40 namespace{ 41 G4Mutex SubEventMutex = G4MUTEX_INITIALIZER; 42 } 43 44 G4Allocator<G4Event>*& anEventAllocator() 45 { 46 G4ThreadLocalStatic G4Allocator<G4Event>* _instance = nullptr; 47 return _instance; 48 } 49 50 G4Event::G4Event(G4int evID) 51 : eventID(evID) 52 { 53 } 54 55 G4Event::~G4Event() 56 { 57 G4PrimaryVertex* nextVertex = thePrimaryVertex; 58 while(nextVertex != nullptr) 59 { 60 G4PrimaryVertex* thisVertex = nextVertex; 61 nextVertex = thisVertex->GetNext(); 62 thisVertex->ClearNext(); 63 delete thisVertex; 64 } 65 thePrimaryVertex = nullptr; 66 delete HC; 67 delete DC; 68 if(trajectoryContainer != nullptr) 69 { 70 trajectoryContainer->clearAndDestroy(); 71 delete trajectoryContainer; 72 } 73 delete userInfo; 74 delete randomNumberStatus; 75 delete randomNumberStatusForProcessing; 76 77 // TODO (PHASE-II): count remaining subevents for scoring 78 for(auto& sem : fSubEvtStackMap) 79 { 80 if((sem.second!=nullptr)&&!(sem.second->empty())) 81 { 82 for(auto& se : *(sem.second)) 83 { delete se; } 84 sem.second->clear(); 85 } 86 } 87 /* TODO (PHASE-II): Handle incorrect scoring 88 if(!scoresRecorded) { 89 G4ExceptionDescription ed; 90 ed << "Deleting G4Event (id:" << eventID << ") that still has unrecorded scores -- " 91 << remainingSE << " sub-events un-processed."; 92 G4Exception("G4Event::~G4Event()","SubEvt0001",FatalException,ed); 93 } else if(remainingSE>0) { 94 G4ExceptionDescription ed; 95 ed << "Deleting G4Event (id:" << eventID << ") that still has " 96 << remainingSE << " sub-events un-processed."; 97 G4Exception("G4Event::~G4Event()","SubEvt0002",FatalException,ed); 98 } 99 */ 100 if(!(fSubEvtVector.empty())) 101 { 102 for(auto& se : fSubEvtVector) 103 { 104 G4cout << "SubEvent " << se << " belongs to " << se->GetEvent() 105 << " (eventID=" << se->GetEvent()->GetEventID() << ") that has " 106 << se->GetNTrack() << " stacked tracks"<<G4endl; 107 } 108 G4ExceptionDescription ed; 109 ed << "Deleting G4Event (id:" << eventID << ") that has " 110 << fSubEvtVector.size() << " sub-events still processing."; 111 G4Exception("G4Event::~G4Event()","SubEvt0003",FatalException,ed); 112 // TODO (PHASE-II): Handle deletion of subevents correctly 113 //for(auto& se : fSubEvtVector) 114 //{ delete se; } 115 //fSubEvtVector.clear(); 116 } 117 118 if(!(fSubEventGarbageBin.empty())) 119 { 120 for(auto& se : fSubEventGarbageBin) 121 { delete se; } 122 fSubEventGarbageBin.clear(); 123 } 124 } 125 126 G4bool G4Event::operator==(const G4Event& right) const 127 { 128 return ( eventID == right.eventID ); 129 } 130 131 G4bool G4Event::operator!=(const G4Event& right) const 132 { 133 return ( eventID != right.eventID ); 134 } 135 136 void G4Event::Print() const 137 { 138 G4cout << "G4Event " << eventID << G4endl; 139 } 140 141 void G4Event::Draw() const 142 { 143 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance(); 144 if(pVVisManager == nullptr) return; 145 146 if(trajectoryContainer != nullptr) 147 { 148 std::size_t n_traj = trajectoryContainer->entries(); 149 for(std::size_t i=0; i<n_traj; ++i) 150 { (*trajectoryContainer)[i]->DrawTrajectory(); } 151 } 152 153 if(HC != nullptr) 154 { 155 std::size_t n_HC = HC->GetCapacity(); 156 for(std::size_t j=0; j<n_HC; ++j) 157 { 158 G4VHitsCollection* VHC = HC->GetHC((G4int)j); 159 if(VHC != nullptr) VHC->DrawAllHits(); 160 } 161 } 162 163 if(DC != nullptr) 164 { 165 std::size_t n_DC = DC->GetCapacity(); 166 for(std::size_t j=0; j<n_DC; ++j) 167 { 168 G4VDigiCollection* VDC = DC->GetDC((G4int)j); 169 if(VDC != nullptr) VDC->DrawAllDigi(); 170 } 171 } 172 } 173 174 G4int G4Event::StoreSubEvent(G4int ty,G4SubEvent* se) 175 { 176 G4AutoLock lock(&SubEventMutex); 177 std::set<G4SubEvent*>* sev = nullptr; 178 auto ses = fSubEvtStackMap.find(ty); 179 if(ses==fSubEvtStackMap.end()) 180 { 181 sev = new std::set<G4SubEvent*>; 182 fSubEvtStackMap[ty] = sev; 183 } 184 else 185 { sev = ses->second; } 186 sev->insert(se); 187 return (G4int)sev->size(); 188 } 189 190 G4SubEvent* G4Event::PopSubEvent(G4int ty) 191 { 192 G4AutoLock lock(&SubEventMutex); 193 G4SubEvent* se = nullptr; 194 auto ses = fSubEvtStackMap.find(ty); 195 if(ses!=fSubEvtStackMap.end()) 196 { 197 auto sev = ses->second; 198 if(!(sev->empty())) 199 { 200 se = sev->extract(sev->begin()).value(); 201 SpawnSubEvent(se); 202 } 203 } 204 return se; 205 } 206 207 G4int G4Event::SpawnSubEvent(G4SubEvent* se) 208 { 209 // Can't use same mutex here as call by PopSubEvent but seems o.k. as only 210 // caller is PopSubEvent 211 //G4AutoLock lock(&SubEventMutex); 212 auto ss = fSubEvtVector.find(se); 213 if(ss!=fSubEvtVector.end()) 214 { 215 G4ExceptionDescription ed; 216 ed << "Sub-event " << se << " of type " << se->GetSubEventType() 217 << " with " << se->GetNTrack() << " tracks has already spawned."; 218 G4Exception("G4Event::SpawnSubEvent","SubEvent9001", 219 FatalException,ed); 220 } 221 fSubEvtVector.insert(se); 222 return (G4int)fSubEvtVector.size(); 223 } 224 225 void G4Event::MergeSubEventResults(const G4Event* /*se*/) 226 { 227 // TODO (PHASE-II): Handle merging of subevent trajectories 228 // Note: 229 // - scores are merged directly to the scoring manager 230 // - hits collections should be merged by the user event action 231 /* 232 #ifdef G4_STORE_TRAJECTORY 233 if(se->trajectoryContainer!=nullptr && se->trajectoryContainer->size()>0) 234 { 235 if(trajectoryContainer==nullptr) trajectoryContainer = new G4TrajectoryContainer; 236 for(auto& trj : *(se->trajectoryContainer->GetVector())) 237 { trajectoryContainer->push_back(trj); } 238 } 239 #endif 240 */ 241 } 242 243 G4int G4Event::TerminateSubEvent(G4SubEvent* se) 244 { 245 G4AutoLock lock(&SubEventMutex); 246 247 auto ss = fSubEvtVector.find(se); 248 if(ss==fSubEvtVector.end()) 249 { 250 G4ExceptionDescription ed; 251 ed << "Sub-event " << se << " of type " << se->GetSubEventType() 252 << " with " << se->GetNTrack() << " tracks of event " << se->GetEvent()->GetEventID() 253 << " in event " << se->GetEvent() 254 << " has never been spawned."; 255 G4Exception("G4Event::TerminateSubEvent","SubEvent9002", 256 FatalException,ed); 257 } 258 259 fSubEvtVector.erase(ss); 260 261 ss = fSubEvtVector.find(se); 262 if(ss!=fSubEvtVector.end()) 263 { 264 G4ExceptionDescription ed; 265 ed << "Sub-event " << se << " of type " << se->GetSubEventType() 266 << " with " << se->GetNTrack() << " appears more than once. PANIC!"; 267 G4Exception("G4Event::TerminateSubEvent","SubEvent9003", 268 FatalException,ed); 269 } 270 271 //se->clearAndDestroy(); 272 //delete se; 273 fSubEventGarbageBin.insert(se); 274 return (G4int)fSubEvtVector.size(); 275 } 276 277 G4int G4Event::GetNumberOfRemainingSubEvents() const 278 // Number of sub-events that are either still waiting to be processed by worker 279 // threads or sent to worker threads but not yet completed. 280 { 281 G4AutoLock lock(&SubEventMutex); 282 auto tot = (G4int)fSubEvtVector.size(); 283 for(auto& sem : fSubEvtStackMap) 284 { tot += (G4int)sem.second->size(); } 285 return tot; 286 } 287