![]() |
![]() |
00001 #include "SimG4Core/Application/interface/SteppingAction.h" 00002 #include "SimG4Core/Application/interface/EventAction.h" 00003 00004 #include "G4Track.hh" 00005 #include "G4PhysicalVolumeStore.hh" 00006 #include "G4UnitsTable.hh" 00007 00008 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00009 00010 using std::cout; 00011 using std::endl; 00012 00013 SteppingAction::SteppingAction(EventAction* e,const edm::ParameterSet & p) 00014 : eventAction_(e), 00015 killBeamPipe(p.getParameter<bool>("KillBeamPipe")), 00016 theCriticalEnergyForVacuum(p.getParameter<double>("CriticalEnergyForVacuum")*MeV), 00017 theCriticalDensity(p.getParameter<double>("CriticalDensity")*g/cm3), 00018 verbose(p.getUntrackedParameter<int>("Verbosity",0)), 00019 initialized(false), tracker(0), calo(0) {} 00020 00021 SteppingAction::~SteppingAction() {} 00022 00023 void SteppingAction::UserSteppingAction(const G4Step * aStep) { 00024 if (!initialized) initialized = initPointer(); 00025 m_g4StepSignal(aStep); 00026 if (killBeamPipe){ 00027 catchLowEnergyInVacuumHere(aStep); 00028 catchLowEnergyInVacuumNext(aStep); 00029 } 00030 if (aStep->GetPostStepPoint()->GetPhysicalVolume() != 0) { 00031 bool ok = (isThisVolume(aStep->GetPreStepPoint()->GetTouchable(),tracker)&& 00032 isThisVolume(aStep->GetPostStepPoint()->GetTouchable(),calo)); 00033 if (ok) { 00034 00035 math::XYZVectorD pos((aStep->GetPreStepPoint()->GetPosition()).x(), 00036 (aStep->GetPreStepPoint()->GetPosition()).y(), 00037 (aStep->GetPreStepPoint()->GetPosition()).z()); 00038 00039 math::XYZTLorentzVectorD mom((aStep->GetPreStepPoint()->GetMomentum()).x(), 00040 (aStep->GetPreStepPoint()->GetMomentum()).y(), 00041 (aStep->GetPreStepPoint()->GetMomentum()).z(), 00042 aStep->GetPreStepPoint()->GetTotalEnergy()); 00043 00044 uint32_t id = aStep->GetTrack()->GetTrackID(); 00045 00046 std::pair<math::XYZVectorD,math::XYZTLorentzVectorD> p(pos,mom); 00047 eventAction_->addTkCaloStateInfo(id,p); 00048 } 00049 } 00050 } 00051 00052 void SteppingAction::catchLowEnergyInVacuumHere(const G4Step * aStep) { 00053 G4Track * theTrack = aStep->GetTrack(); 00054 double theKenergy = theTrack->GetKineticEnergy(); 00055 if (theTrack->GetVolume()!=0) { 00056 double density = theTrack->GetVolume()->GetLogicalVolume()->GetMaterial()->GetDensity(); 00057 if (theKenergy <= theCriticalEnergyForVacuum && theKenergy > 0.0 && 00058 density <= theCriticalDensity && theTrack->GetDefinition()->GetPDGCharge() != 0 && 00059 theTrack->GetTrackStatus() != fStopAndKill) { 00060 if (verbose>1) 00061 edm::LogInfo("SimG4CoreApplication") 00062 << " SteppingAction: LoopCatchSteppingAction:catchLowEnergyInVacuumHere: " 00063 << " Track from " << theTrack->GetDefinition()->GetParticleName() 00064 << " of kinetic energy " << theKenergy/MeV << " MeV " 00065 << " killed in " << theTrack->GetVolume()->GetLogicalVolume()->GetName() 00066 << " of density " << density/(g/cm3) << " g/cm3" ; 00067 theTrack->SetTrackStatus(fStopAndKill); 00068 } 00069 } 00070 } 00071 00072 void SteppingAction::catchLowEnergyInVacuumNext(const G4Step * aStep) { 00073 G4Track * theTrack = aStep->GetTrack(); 00074 double theKenergy = theTrack->GetKineticEnergy(); 00075 if (theTrack->GetNextVolume()) { 00076 double density = theTrack->GetNextVolume()->GetLogicalVolume()->GetMaterial()->GetDensity(); 00077 if (theKenergy <= theCriticalEnergyForVacuum && theKenergy > 0.0 && 00078 density <= theCriticalDensity && theTrack->GetDefinition()->GetPDGCharge() != 0 && 00079 theTrack->GetTrackStatus() != fStopAndKill) { 00080 if (verbose>1) 00081 edm::LogInfo("SimG4CoreApplication") 00082 << " SteppingAction: LoopCatchSteppingAction::catchLowEnergyInVacuumNext: " 00083 << " Track from " << theTrack->GetDefinition()->GetParticleName() 00084 << " of kinetic energy " << theKenergy/MeV << " MeV " 00085 << " stopped in " << theTrack->GetVolume()->GetLogicalVolume()->GetName() 00086 << " before going into "<< theTrack->GetNextVolume()->GetLogicalVolume()->GetName() 00087 << " of density " << density/(g/cm3) << " g/cm3" ; 00088 theTrack->SetTrackStatus(fStopButAlive); 00089 } 00090 } 00091 } 00092 00093 bool SteppingAction::initPointer() { 00094 00095 const G4PhysicalVolumeStore * pvs = G4PhysicalVolumeStore::GetInstance(); 00096 if (pvs) { 00097 std::vector<G4VPhysicalVolume*>::const_iterator pvcite; 00098 for (pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) { 00099 if ((*pvcite)->GetName() == "Tracker") tracker = (*pvcite); 00100 if ((*pvcite)->GetName() == "CALO") calo = (*pvcite); 00101 if (tracker && calo) break; 00102 } 00103 edm::LogInfo("SimG4CoreApplication") << "Pointer for Tracker " << tracker 00104 << " and for Calo " << calo; 00105 if (tracker) LogDebug("SimG4CoreApplication") << "Tracker vol name " 00106 << tracker->GetName(); 00107 if (calo) LogDebug("SimG4CoreApplication") << "Calorimeter vol name " 00108 << calo->GetName(); 00109 return true; 00110 } 00111 return false; 00112 } 00113 00114 bool SteppingAction::isThisVolume(const G4VTouchable* touch, 00115 G4VPhysicalVolume* pv) { 00116 00117 int level = ((touch->GetHistoryDepth())+1); 00118 if (level > 0 && level >= 3) { 00119 int ii = level - 3; 00120 return (touch->GetVolume(ii) == pv); 00121 } 00122 return false; 00123 }