00001
00002
00003
00004 #include "TrajectoryManager.hh"
00005 #include "Trajectory.hh"
00006
00007
00008 #include "G4TrackVector.hh"
00009 #include "G4Event.hh"
00010
00011 namespace slic
00012 {
00013
00014 TrajectoryManager::~TrajectoryManager()
00015 {}
00016
00017 TrajectoryManager::TrajectoryManager()
00018 : Module("TrajectoryManager"),
00019 m_trackingManager(0),
00020 m_currentTrajectory(0),
00021 m_currentTrack(0),
00022 m_currentTrackID(-1)
00023 {}
00024
00025 void TrajectoryManager::preTracking(const G4Track* aTrack)
00026 {
00027 m_currentTrack = aTrack;
00028 m_currentTrackID = aTrack->GetTrackID();
00029
00030 #ifdef SLIC_LOG
00031 log() << LOG::verbose
00032 << "TrajectoryManager::preTracking()" << LOG::endl
00033 << "trackID <" << aTrack->GetTrackID() << ">" << LOG::endl
00034 << "particle <" << aTrack->GetDefinition()->GetParticleName() << ">" << LOG::endl
00035 << "volume <" << aTrack->GetVolume()->GetName() << ">"
00036 << LOG::done;
00037 printStatusFlags(aTrack);
00038 #endif
00039
00040
00041 m_trackingManager->SetStoreTrajectory( false );
00042
00043
00044 if ( isPrimaryTrack(aTrack) ) {
00045 handlePrimaryTrack( aTrack );
00046 }
00047 else {
00048 handleSecondaryTrack( aTrack );
00049 }
00050 }
00051
00052 void TrajectoryManager::printStatusFlags( const G4Track* trk)
00053 {
00054 log() << LOG::debug << "status flags for trackID <" << trk->GetTrackID() << ">" << LOG::done;
00055 printStatusFlags( TrackInformation::getTrackInformation( trk ) );
00056 }
00057
00058 void TrajectoryManager::printStatusFlags(TrackInformation* trkInfo)
00059 {
00060 if ( trkInfo ) {
00061 log() << LOG::verbose
00062 << "tracking status <" << TrackInformation::getTrackingStatusString( trkInfo->getTrackingStatus() ) << ">" << LOG::endl
00063 << "orig tracking status <" << TrackInformation::getTrackingStatusString( trkInfo->getOriginalTrackingStatus() ) << ">" << LOG::endl
00064 << "backscatter flag <" << trkInfo->getBackscatter() << ">" << LOG::endl
00065 << "belowThreshold flag <" << trkInfo->getBelowThreshold() << ">" << LOG::endl
00066 << "tracker hit flag <" << trkInfo->hasTrackerHit() << ">" << LOG::endl
00067 << "vtxnotendp flag <" << trkInfo->getVertexIsNotEndpointOfParent() << ">"
00068 << LOG::done;
00069 }
00070 #ifdef SLIC_LOG
00071 else {
00072 log() << LOG::debug << "Track info NULL in printStatusFlags()." << LOG::done;
00073 }
00074 #endif
00075 }
00076
00077 void TrajectoryManager::printTrajectory(const Trajectory* trj)
00078 {
00079 log() << LOG::debug
00080 << "trajectory info" << LOG::endl
00081 << "trackID <" << trj->GetTrackID() << ">" << LOG::endl
00082 << "final status: " << trj->getFinalStatusString() << LOG::endl
00083 << "endp dau: " << trj->getHasEndpointDaughters() << LOG::endl
00084 << "backscatter: " << trj->getBackscatter() << LOG::endl
00085 << "vtxnotendp: " << trj->getVertexIsNotEndpointOfParent() << LOG::endl
00086 << "created in sim: " << trj->getCreatedInSimulation() << LOG::endl
00087 << "vtx: " << trj->GetPoint(0)->GetPosition() << LOG::endl
00088 << "endp: " << trj->GetPoint(trj->GetPointEntries() - 1)->GetPosition() << LOG::endl
00089 << LOG::done;
00090 }
00091
00092 void TrajectoryManager::postTracking(const G4Track* aTrack)
00093 {
00094 #ifdef SLIC_LOG
00095 log() << LOG::verbose << "TrajectoryManager::postTracking()" << LOG::endl;
00096 #endif
00097
00098
00099 if ( needsManualTrajectorySetup( aTrack ) ) {
00100
00101 #ifdef SLIC_LOG
00102 log() << LOG::verbose << "needs manual trajectory setup" << LOG::done;
00103 #endif
00104
00105
00106 Trajectory* trj = createTrajectoryFromTrack( aTrack );
00107
00108
00109 trj->setupManuallyFromTrack( aTrack );
00110 }
00111
00112
00113 copySecondaryTrackInformationFromParent( aTrack );
00114
00115
00116 setTrajectoryFinalStatus( aTrack );
00117
00118
00119 #ifdef SLIC_LOG
00120 log() << LOG::verbose << "store trajectory <" << m_trackingManager->GetStoreTrajectory() << ">" << LOG::done;
00121 #endif
00122
00123
00124 #ifdef SLIC_LOG
00125 printStatusFlags(aTrack);
00126 #endif
00127
00128 Trajectory* trj = static_cast<Trajectory*>(m_trackingManager->GimmeTrajectory());
00129 if ( 0 != trj ) {
00130 trj->setEndpointEnergy( aTrack->GetTotalEnergy() );
00131 }
00132 }
00133
00134 void TrajectoryManager::handlePrimaryTrack(const G4Track* aTrack)
00135 {
00136
00137 setPrimaryTrackInformation(aTrack);
00138
00139
00140 createTrajectoryFromTrack( aTrack );
00141 }
00142
00143 Trajectory* TrajectoryManager::createTrajectoryFromTrack(const G4Track* aTrack )
00144 {
00145 Trajectory* trj = new Trajectory( aTrack );
00146 m_trackingManager->SetStoreTrajectory( true );
00147 m_trackingManager->SetTrajectory( trj );
00148 addTrackIDToTrajectoryLink( trj );
00149 m_currentTrajectory = trj;
00150 return trj;
00151 }
00152
00153 void TrajectoryManager::setPrimaryTrackInformation(const G4Track* aTrack)
00154 {
00155 TrackInformation* trkInfo = new TrackInformation( aTrack );
00156
00157
00158 setTrackingFlagFromRegionInformation( trkInfo, G4UserRegionInformation::getRegionInformation( aTrack ) );
00159
00160 G4Track* nconstTrack = const_cast<G4Track*> (aTrack);
00161 nconstTrack->SetUserInformation( trkInfo );
00162 }
00163
00164 void TrajectoryManager::setTrackingFlagFromRegionInformation(TrackInformation* trk_info, G4UserRegionInformation* reg_info)
00165 {
00166 if ( reg_info->getStoreSecondaries() == true ) {
00167 trk_info->setTrackingStatus(TrackInformation::eInTrackingRegion);
00168 }
00169 else {
00170 trk_info->setTrackingStatus(TrackInformation::eInNontrackingRegion);
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179 void TrajectoryManager::handleSecondaryTrack(const G4Track* aTrack)
00180 {
00181
00182 TrackInformation* trkInfo = TrackInformation::getTrackInformation( aTrack );
00183
00184
00185 G4UserRegionInformation* regInfo = G4UserRegionInformation::getRegionInformation ( aTrack );
00186
00187
00188 if ( regInfo && trkInfo ) {
00189
00190
00191 if ( regInfo->getStoreSecondaries() ) {
00192
00193
00194 if ( isBackscatter( aTrack ) ) {
00195 trkInfo->setBackscatter( true );
00196 }
00197
00198
00199
00200
00201
00202 else if ( isBelowThreshold( aTrack ) &&
00203 trkInfo->getVertexIsNotEndpointOfParent() ) {
00204 trkInfo->setBelowThreshold( true );
00205 }
00206
00207
00208
00209
00210
00211 else {
00212
00213
00214 setupSecondaryTrackInformation( aTrack );
00215
00216
00217 createSecondaryTrajectory( aTrack );
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 TrackInformation::getTrackInformation( aTrack )
00242 ->setTrackingStatus( TrackInformation::eInTrackingRegion );
00243 }
00244
00245 else {
00246
00247
00248 trkInfo->setTrackingStatus( TrackInformation::eInNontrackingRegion );
00249 trkInfo->setOriginalTrackingStatus( TrackInformation::eInNontrackingRegion );
00250 }
00251 }
00252
00253 else {
00254 log() << LOG::fatal << "FATAL ERROR: region info or track info were null in handleSecondaryTrack()." << LOG::endl
00255 << "region info <" << regInfo << ">" << LOG::endl
00256 << "track info <" << trkInfo << ">" << LOG::done;
00257 G4Exception("Track info or region info was null.");
00258 }
00259 }
00260
00261 void TrajectoryManager::setupSecondaryTrackInformation(const G4Track* aTrack)
00262 {
00263
00264 TrackInformation* oldTrkInfo = TrackInformation::getTrackInformation( aTrack );
00265
00266
00267 TrackInformation* newTrkInfo = new TrackInformation( aTrack );
00268
00269
00270 newTrkInfo->setVertexIsNotEndpointOfParent( oldTrkInfo->getVertexIsNotEndpointOfParent() );
00271
00272
00273
00274
00275 delete oldTrkInfo;
00276 oldTrkInfo = 0;
00277
00278
00279
00280
00281
00282
00283 newTrkInfo->setOriginalTrackingStatus( TrackInformation::eInTrackingRegion );
00284
00285
00286
00287
00288 G4Track* nconstTrk = const_cast<G4Track*> ( aTrack );
00289 nconstTrk->SetUserInformation( newTrkInfo );
00290 }
00291
00292 Trajectory* TrajectoryManager::createSecondaryTrajectory(const G4Track* aTrack)
00293 {
00294
00295 Trajectory* trj = createTrajectoryFromTrack( aTrack );
00296
00297
00298 trj->setCreatedInSimulation( true );
00299
00300 return trj;
00301 }
00302
00303
00304 void TrajectoryManager::copySecondaryTrackInformationFromParent(const G4Track* aTrack)
00305 {
00306
00307 TrackInformation* parTrkInfo = TrackInformation::getTrackInformation( aTrack );
00308
00309
00310 Trajectory* parTrj = getCurrentTrajectory();
00311
00312
00313 G4TrackVector* secondaries = m_trackingManager->GimmeSecondaries();
00314
00315
00316 if ( secondaries ) {
00317 size_t nseco = secondaries->size();
00318 for ( size_t i = 0; i < nseco; i++ ) {
00319
00320
00321 G4Track* seco = (*secondaries)[i];
00322
00323
00324 TrackInformation* secoTrkInfo = new TrackInformation( parTrkInfo );
00325 seco->SetUserInformation( secoTrkInfo );
00326
00327
00328 if ( parTrj ) {
00329
00330
00331 G4ThreeVector parEndpoint = getTrajectoryEndpoint( parTrj );
00332
00333
00334 if ( secoTrkInfo->getOriginalTrackID() != aTrack->GetTrackID() ||
00335 vertexIsNotEndpointOfParent( parEndpoint, seco ) ) {
00336
00337
00338 secoTrkInfo->setVertexIsNotEndpointOfParent( true );
00339 }
00340 }
00341
00342 else {
00343 secoTrkInfo->setVertexIsNotEndpointOfParent( true );
00344 }
00345 }
00346
00347 #ifdef SLIC_LOG
00348 log() << LOG::verbose << "track info passed to <" << nseco << "> secondaries" << LOG::endl;
00349 #endif
00350 }
00351 }
00352
00353 bool TrajectoryManager::needsManualTrajectorySetup(const G4Track* aTrack)
00354 {
00355
00356 return ( !m_trackingManager->GetStoreTrajectory() ) &&
00357 ( TrackInformation::getTrackInformation( aTrack )->hasTrackerHit() );
00358 }
00359
00360 void TrajectoryManager::stepping(const G4Step* aStep)
00361 {
00362 const G4Track* theTrack = aStep->GetTrack();
00363
00364
00365 if ( isAlive( aStep ) ) {
00366
00367 TrackInformation* trkInfo = TrackInformation::getTrackInformation( theTrack );
00368
00369 G4UserRegionInformation* preReg = G4UserRegionInformation::getRegionInformation( aStep->GetPreStepPoint() );
00370 G4UserRegionInformation* postReg = G4UserRegionInformation::getRegionInformation( aStep->GetPostStepPoint() );
00371
00372
00373 if ( preReg && postReg ) {
00374
00375
00376 if ( preReg->getStoreSecondaries() && ( !postReg->getStoreSecondaries() ) ) {
00377 trkInfo->setTrackingStatus( TrackInformation::eInNontrackingRegion );
00378 }
00379
00380 else if ( !preReg->getStoreSecondaries() && postReg->getStoreSecondaries() ) {
00381 TrackInformation::ETrackingStatus origStatus = trkInfo->getOriginalTrackingStatus();
00382
00383
00384 if ( ! ( origStatus == TrackInformation::eInTrackingRegion ) ) {
00385 trkInfo->setBackscatter(true);
00386 }
00387
00388
00389 trkInfo->setTrackingStatus( TrackInformation::eInTrackingRegion );
00390 }
00391 }
00392 }
00393 }
00394
00395 void TrajectoryManager::setTrajectoryFinalStatus(const G4Track* aTrack)
00396 {
00397
00398 Trajectory* trj = getCurrentTrajectory();
00399
00400
00401 if ( trj ) {
00402
00403 G4StepPoint* postStep = aTrack->GetStep()->GetPostStepPoint();
00404
00405
00406 TrackInformation* trkInfo =
00407 TrackInformation::getTrackInformation( aTrack );
00408
00409
00410 G4int nSecoAtEnd = getNumberOfSecondariesAtEnd( aTrack );
00411 if ( nSecoAtEnd > 0 ) {
00412 trj->setHasEndpointDaughters( true );
00413 }
00414
00415
00416 Trajectory::EFinalStatus finalStatus = Trajectory::eUnset;
00417
00418
00419 trj->setBackscatter( trkInfo->getBackscatter() );
00420
00421
00422 if ( trkInfo->getVertexIsNotEndpointOfParent() ) {
00423 trj->setVertexIsNotEndpointOfParent( true );
00424 }
00425
00426
00427 if ( nSecoAtEnd <= 0 ) {
00428
00429 if ( !postStep->GetMaterial() ) {
00430 finalStatus = Trajectory::eLeftDetector;
00431 }
00432
00433
00434 else if ( aTrack->GetKineticEnergy() <= 0. ) {
00435 finalStatus = Trajectory::eStopped;
00436 }
00437
00438 #ifdef SLIC_DEBUG
00439 else {
00440 log() << LOG::debug << "Unknown decay case (probably a looper)." << LOG::done;
00441 }
00442 #endif
00443 }
00444
00445 else {
00446
00447
00448 if ( trkInfo->getTrackingStatus() == TrackInformation::eInTrackingRegion ) {
00449 finalStatus = Trajectory::eDecayedInTracker;
00450 }
00451
00452 else {
00453 finalStatus = Trajectory::eDecayedInCalorimeter;
00454 }
00455 }
00456
00457
00458 trj->setFinalStatus( finalStatus );
00459 }
00460 }
00461
00462 void TrajectoryManager::printTrack(const G4Track* trk, bool isSecondary)
00463 {
00464 log() << LOG::endl;
00465 log() << "track ptr <" << trk << ">" << LOG::endl;
00466 log() << "trackID <" << trk->GetTrackID() << ">" << LOG::endl;
00467 log() << "parent trackID <" << trk->GetParentID() << ">" << LOG::endl;
00468 log() << "PDG <" << trk->GetDefinition()->GetPDGEncoding() << ">" << LOG::endl;
00469 log() << "position <" << trk->GetPosition() << ">" << LOG::endl;
00470
00471 if ( !isSecondary ) {
00472 if ( trk->GetMaterial() ) {
00473 log() << "material <" << trk->GetMaterial()->GetName() << ">" << LOG::endl;
00474 }
00475 else {
00476 log() << "NO material" << LOG::endl;
00477 }
00478
00479 if ( trk->GetVolume() ) {
00480 log() << "volume <" << trk->GetVolume()->GetName() << ">" << LOG::endl;
00481 }
00482 else {
00483 log() << "NO volume" << LOG::endl;
00484 }
00485 }
00486
00487 if ( !isSecondary ) {
00488 log() << "numSecoAtEnd <" << getNumberOfSecondariesAtEnd(trk) << ">" << LOG::endl;
00489 }
00490
00491 log() << "kE <" << trk->GetKineticEnergy() << ">" << LOG::endl;
00492 log() << "mom <" << trk->GetMomentum() << ">" << LOG::endl;
00493
00494 printStatusFlags(trk);
00495
00496 log() << LOG::endl;
00497 }
00498
00499 void TrajectoryManager::printPhysVolDbg(G4StepPoint* stepPnt)
00500 {
00501 if ( stepPnt ) {
00502 G4VPhysicalVolume* pv = stepPnt->GetPhysicalVolume();
00503
00504 if ( pv ) {
00505 log() << LOG::debug << "PV name <" << pv->GetName() << ">" << LOG::endl;
00506 }
00507 else {
00508 log() << LOG::debug << "PV is NULL!" << LOG::endl;
00509 }
00510 }
00511 }
00512
00513
00514 G4int TrajectoryManager::getNumberOfSecondariesAtEnd(const G4Track* aTrack)
00515 {
00516 G4int numSecoAtEnd = 0;
00517 G4TrackVector* seco = m_trackingManager->GimmeSecondaries();
00518 G4ThreeVector endPnt = aTrack->GetPosition();
00519
00520 if ( seco ) {
00521 size_t numSeco = seco->size();
00522
00523 #ifdef SLIC_LOG
00524 log() << LOG::debug << "numSeco <" << numSeco << ">" << LOG::endl;
00525 #endif
00526
00527 for( size_t i = 0;
00528 i < numSeco;
00529 i++ ) {
00530
00531 if ( (*seco)[i]->GetPosition().isNear( endPnt ) ) {
00532 ++numSecoAtEnd;
00533 }
00534 }
00535 }
00536
00537 #ifdef SLIC_LOG
00538 log() << LOG::debug << "found numSecoAtEnd <" << numSecoAtEnd << ">" << LOG::endl;
00539 #endif
00540
00541 return numSecoAtEnd;
00542 }
00543
00544
00545 void TrajectoryManager::fillTrackIDToTrajectoryMap( const G4Event* anEvent, bool clearIt)
00546 {
00547 if ( clearIt ) {
00548 clearTrackIDToTrajectoryMap();
00549 }
00550
00551 G4TrajectoryContainer* trajCont = anEvent->GetTrajectoryContainer();
00552
00553 if ( trajCont ) {
00554 G4int n_traj = trajCont->entries();
00555
00556 Trajectory* trj = 0;
00557 for ( int i=0; i < n_traj; i++ ) {
00558 trj = static_cast<Trajectory*> ( (*trajCont)[i] );
00559
00560 addTrackIDToTrajectoryLink( trj );
00561 }
00562 }
00563 else {
00564 log() << LOG::error << "Cannot fill map without a trajectory container!" << LOG::endl;
00565 }
00566 }
00567
00568 void TrajectoryManager::addTrackIDToTrajectoryLink( Trajectory* trj)
00569 {
00570 if ( trj ) {
00571 m_trackIDToTrajectory[ trj->GetTrackID() ] = trj;
00572 }
00573 else {
00574 log() << LOG::error << "Trajectory is null!" << LOG::endl;
00575 }
00576 }
00577
00578 void TrajectoryManager::printSecondaries()
00579 {
00580 log() << LOG::debug
00581 << "secondaries for trackID <"
00582 << m_trackingManager->GetTrack()->GetTrackID()
00583 << ">"
00584 << LOG::done;
00585
00586 G4TrackVector* secondaries = m_trackingManager->GimmeSecondaries();
00587 size_t nseco = secondaries->size();
00588 for ( size_t i = 0; i < nseco; i++ ) {
00589
00590
00591 G4Track* seco = (*secondaries)[i];
00592 log() << LOG::debug << "secondary track <" << i << ">" << LOG::endl;
00593 printTrack( seco, true );
00594 }
00595 }
00596
00597
00598 Trajectory* TrajectoryManager::findTrajectory(G4int trkID)
00599 {
00600 #ifdef SLIC_LOG
00601 log() << LOG::debug << "findTrajectory() - trkID <" << trkID << ">" << LOG::endl;
00602 #endif
00603
00604 Trajectory* trj = 0;
00605 TrackIDToTrajectoryMap::iterator iter;
00606
00607 iter = m_trackIDToTrajectory.find( trkID );
00608
00609 if ( iter != m_trackIDToTrajectory.end() ) {
00610 trj = iter->second;
00611 }
00612
00613 #ifdef SLIC_LOG
00614 if ( trj ) {
00615 log() << LOG::debug << "found trajectory" << LOG::endl;
00616 }
00617 else {
00618 log() << LOG::debug << "no trajectory found" << LOG::endl;
00619 }
00620 #endif
00621
00622 return trj;
00623 }
00624 }