222 lines
9.2 KiB
C++
Executable File
222 lines
9.2 KiB
C++
Executable File
// 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 <string>
|
|
#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<MAXofPostStepLoops; i++)
|
|
{
|
|
G4VProcess* fCurrentProcess = (*fPostStepDoItVector)[i];
|
|
opBoundaryProcess = dynamic_cast<G4OpBoundaryProcess*>(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 ++ */
|
|
}
|