// Written by Peter Stromberger // based on work of Mirco Deckenhoff // modified by Bastian Rössler #include "SteppingAction.hh" #include "G4Step.hh" #include "G4VTouchable.hh" #include "G4SteppingManager.hh" #include "G4UnitsTable.hh" #include "G4ParticleTypes.hh" #include "G4ProcessManager.hh" #include "G4VProcess.hh" #include "G4ProcessVector.hh" #include "EventAction.hh" #include #include "Parameters.hh" #include "Analysis.hh" #include "G4RunManager.hh" #include "Randomize.hh" #include "G4SystemOfUnits.hh" SteppingAction::SteppingAction(EventAction* eventAction, PrimaryGeneratorAction* p) { creatorProcess = -1; fEventAction = eventAction; pGA = p; } SteppingAction::~SteppingAction(){} void SteppingAction::UserSteppingAction( const G4Step * step ) { primDefinition = (pGA->GetGun())->GetParticleDefinition(); primParticle = (primDefinition->GetParticleName()).c_str(); /* ++ SteppingAction for optical photons ++ */ if(step->GetTrack()->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) { G4int trackId = step->GetTrack()->GetTrackID(); G4double stepLength = step->GetStepLength(); G4String prePhysicalVolumeName = step->GetPreStepPoint()->GetPhysicalVolume()->GetName(); G4String postPhysicalVolumeName = ""; // PostStep does only exist if the particle is not exiting the EpoxyBox volume! if(step->GetTrack()->GetTrackStatus() != fStopAndKill) postPhysicalVolumeName = step->GetPostStepPoint()->GetPhysicalVolume()->GetName(); // Kill photons at fibre surface // Count the reflections and refractions if(step->GetPostStepPoint()->GetStepStatus()==fGeomBoundary) { if(postPhysicalVolumeName == "EpoxyBox" && prePhysicalVolumeName.substr(0,9) == "Cladding2") { if(Parameters::GetInstance()->ProbabilityOfPhotonLossAtSurface() == 1) step->GetTrack()->SetTrackStatus(fStopAndKill); if(Parameters::GetInstance()->ProbabilityOfPhotonLossAtSurface() < 1 && Parameters::GetInstance()->ProbabilityOfPhotonLossAtSurface() > 0) { G4double randomNumber = CLHEP::RandFlat::shoot(); if(Parameters::GetInstance()->ProbabilityOfPhotonLossAtSurface() < randomNumber) { if (step->GetStepLength() > 0) Analysis::GetInstance()->IncreaseReflectionsAtFibreSurface(trackId); } else step->GetTrack()->SetTrackStatus(fStopAndKill); } if (step->GetStepLength() > 0) Analysis::GetInstance()->IncreaseReflectionsAtFibreSurface(trackId); } if(postPhysicalVolumeName == "Mirror") Analysis::GetInstance()->IncreaseReflectionsAtMirror(trackId); // Retrieve status of the photon boundary process G4OpBoundaryProcessStatus theBoundaryStatus = Undefined; G4ProcessManager* OpManager = G4OpticalPhoton::OpticalPhoton()->GetProcessManager(); if(OpManager) { G4int MAXofPostStepLoops = OpManager->GetPostStepProcessVector()->entries(); G4ProcessVector* fPostStepDoItVector = OpManager->GetPostStepProcessVector(typeDoIt); for(G4int i = 0; i(fCurrentProcess); if(opBoundaryProcess) { theBoundaryStatus = opBoundaryProcess->GetStatus(); break; } } } if(theBoundaryStatus != Undefined) { if((prePhysicalVolumeName.substr(0,9) == "Cladding1" && postPhysicalVolumeName.substr(0,9) == "Cladding2") || (prePhysicalVolumeName.substr(0,9) == "Cladding2" && postPhysicalVolumeName.substr(0,9) == "Cladding1")) { if(theBoundaryStatus == TotalInternalReflection) Analysis::GetInstance()->IncreaseTotalReflectionsAtCladCladInterface(trackId); if(theBoundaryStatus == FresnelReflection) Analysis::GetInstance()->IncreaseFresnelReflectionsAtCladCladInterface(trackId); if(theBoundaryStatus == FresnelRefraction) Analysis::GetInstance()->IncreaseRefractionsAtCladCladInterface(trackId); } if ((prePhysicalVolumeName.substr(0,4) == "Core" && postPhysicalVolumeName.substr(0,9) == "Cladding1") || (prePhysicalVolumeName.substr(0,9) == "Cladding1" && postPhysicalVolumeName.substr(0,9) == "Core")) { if(theBoundaryStatus == TotalInternalReflection) Analysis::GetInstance()->IncreaseTotalReflectionsAtCoreCladInterface(trackId); if(theBoundaryStatus == FresnelReflection) Analysis::GetInstance()->IncreaseFresnelReflectionsAtCoreCladInterface(trackId); if(theBoundaryStatus == FresnelRefraction) Analysis::GetInstance()->IncreaseRefractionsAtCoreCladInterface(trackId); } } } else // Check for Rayleigh scattering if (step->GetDeltaMomentum()[0] != 0 || step->GetDeltaMomentum()[1] != 0 || step->GetDeltaMomentum()[2] != 0) Analysis::GetInstance()->IncreaseRayleighScatterings(trackId); // Store length per volume if (prePhysicalVolumeName.substr(0,4) == "Core") Analysis::GetInstance()->IncreaseLengthInCore(trackId,stepLength); if (prePhysicalVolumeName.substr(0,9) == "Cladding1") Analysis::GetInstance()->IncreaseLengthInInnerCladding(trackId,stepLength); if (prePhysicalVolumeName.substr(0,9) == "Cladding2") Analysis::GetInstance()->IncreaseLengthInOuterCladding(trackId,stepLength); // Store photons killed by OpWLS process, if not primary particle if(step->GetTrack()->GetParentID() > 0 && step->GetTrack()->GetTrackStatus() == fStopAndKill && step->GetSecondary()->size() == 1) { G4int creatorProcessId = 0; if(step->GetTrack()->GetCreatorProcess()->GetProcessName() == "Scintillation") creatorProcessId = 1; if(step->GetTrack()->GetCreatorProcess()->GetProcessName() == "Cerenkov") creatorProcessId = 2; if(step->GetTrack()->GetCreatorProcess()->GetProcessName() == "OpWLS") creatorProcessId = 3; } // Radiation damage dose = h_dose->GetBinContent(1,1 ); dose = 0; std::cout << step->GetTrack()->GetPosition().x() << " " << step->GetTrack()->GetPosition().y() << " " << step->GetTrack()->GetPosition().z() << " " << dose << "\n "; G4float attlength = 100.*1./(dose * 1.5*exp(9.412 -0.0256721 * 1240./(step->GetTrack()->GetTotalEnergy()/eV)) ); double xf = G4UniformRand(); //std::cout << xf << " " << attlength<< " " << 1240./(step->GetTrack()->GetTotalEnergy()/eV) << "\n"; if(xf>(exp(-stepLength*cm/attlength)) ){ //randomly kill photon based on attenuation length step->GetTrack()->SetTrackStatus(fStopAndKill);} } /* ++ End of SteppingAction of optical photons. ++ */ /* ++ SteppingAction for electrons and muon ++ */ if((step->GetTrack()->GetDefinition() == primDefinition)) { G4double runID = (G4double) G4RunManager::GetRunManager()->GetCurrentRun()->GetRunID(); G4double eventID = (G4double) G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID(); Analysis::GetInstance()->FillPrimaryParticleTrack(runID, eventID, step->GetTrack()->GetPosition()[0], step->GetTrack()->GetPosition()[1], step->GetTrack()->GetPosition()[2]); G4String prePhysicalVolumeName = step->GetPreStepPoint()->GetPhysicalVolume()->GetName(); if (prePhysicalVolumeName.substr(0,4) == "Core") { G4double edep = step->GetTotalEnergyDeposit(); G4double stepLength = step->GetStepLength(); fEventAction->AddCore(edep, stepLength); } if (prePhysicalVolumeName == "Trigger") { G4double edep = step->GetTotalEnergyDeposit(); Analysis::GetInstance()->FillTrigger(runID, eventID, edep, step->GetTrack()->GetPosition()[0], step->GetTrack()->GetPosition()[1], step->GetTrack()->GetPosition()[2]); } } /* ++ End of SteppingAction for electrons and muon ++ */ }