//////////////////////////////////////////////////////////////////////////////
//
// Useful optical functions. All Optical Models should derive from this.
// Implements Reflect, Refract, Diffuse Reflect, Polarisation, tracking,
// ids etc... Utility functions that all Optical Models need.
//
// Author: Phil G Jones
//
// REVISION HISTORY:
// 05/11/2010 : P G Jones - New file
// 2014-08-05 : P G Jones - Updated doxygen.
// 2016-10-23 : N Barros - Added a history word to the photoelectron.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __RAT_OpticalModelBase_hh__
#define __RAT_OpticalModelBase_hh__
#include
#include
class G4FastTrack;
namespace RAT
{
namespace DS {
class MCPE;
}
class OpticalModelBase
{
public:
// Constructor, sets the models tolerance and max iterations
OpticalModelBase();
// Enum of allowed polarisations, S or P
enum EPolarisation { esPolarised, epPolarised };
protected:
// Returns S fraction of the polarisation, P fraction is 1-S
//
// normal: normal of the surface in local coords
// direction: direction of the track in local coords
// polarisation: polarisation of the track in local coords
// Returns S fraction [0, 1]
double GetSPolarisationFraction( const G4ThreeVector& normal,
const G4ThreeVector& direction,
const G4ThreeVector& polarisation );
// Returns the polarisation, throws a dice and decides
//
// normal: normal of the surface in local coords
// direction: direction of the track in local coords
// polarisation: polarisation of the track in local coords
// Returns polarisation type
EPolarisation GetPolarisation( const G4ThreeVector& normal,
const G4ThreeVector& direction,
const G4ThreeVector& polarisation );
// Reflects the direction & polarisation such that angle_incidence = angle_reflection.
// This expects normal dot direction < 0, i.e. the normal to point out of a surface the photon heads into.
//
// normal: normal of the surface in local coords
// direction: direction of the track in local coords
// polarisation: polarisation of the track in local coords
void NormalReflect( const G4ThreeVector& normal, G4ThreeVector& direction,
G4ThreeVector& polarisation );
// Diffuse reflects the direction & polarisation
// This expects normal dot direction < 0, i.e. the normal to point out of a surface the photon heads into.
//
// normal: normal of the surface in local coords
// direction: direction of the track in local coords
// polarisation: polarisation of the track in local coords
void DiffuseReflect( const G4ThreeVector& normal, G4ThreeVector& direction,
G4ThreeVector& polarisation );
// Refracts the direction & polarisation from outer media into inner media
// This expects normal dot direction < 0, i.e. the normal to point out of a surface the photon heads into.
//
// normal: normal of the surface in local coords
// n1: Refractive Index of outer media
// n2: Refractive Index of Inner media
// direction: direction of the track in local coords
// polarisation: polarisation of the track in local coords
void Refract( const G4ThreeVector& normal, const G4double n1,
const G4double n2, G4ThreeVector& direction,
G4ThreeVector& polarisation );
// Produces a photon with anle theta to the normal and azimuthal phi angle to arbitrary direction/
// This expects normal dot direction < 0, i.e. the normal to point out of a surface the photon heads into.
// Ported from pmt_rayscatter.for
//
// normal: normal of the surface in local coords
// theta: angle to normal
// phi: angle around normal (azimuthal)
// resp: response/constructed vector
void RayScatter( const G4ThreeVector& normal, const G4double theta,
const G4double phi, G4ThreeVector& resp );
// Add a trajectory step to the ds output
//
// fastTrack: track of the photon
// endPos: ending position of the step in local co-ords
// direction: direction of the step in local co-ords
// stepLength: step length in mm
// time: global time at the end of the step
// energy: energy at the end of the step
// startVolume: name of the starting volume
// endVolume: name of the ending volume
void RecordTrajectory( const G4FastTrack& fastTrack,
const G4ThreeVector& endPos,
const G4ThreeVector& direction,
const G4double stepLength,
const G4double time,
const G4double energy,
const std::string& startVolume,
const std::string& endVolume );
// Add a final trajectory step
//
// pmtID: PMT id where the photoelectron was created
void RecordPhotoelectron( const int pmtID );
// Return the PMT id, tracks back through track history to find which PMT it is in
//
// fastTrack: track of the photon
// Returns the PMT id
int GetPMTID( const G4FastTrack& fastTrack );
// Set the dot product between the direction on entry to the bucket and the
// bucket surface normal
//
// trackID: track ID of the photon
// pmtID: PMT the photon is entering
// bucketCos: of the photon direction and bucket surface normal
static void SetBucketCos( const G4int trackID, const G4int pmtID,
const G4double bucketCos );
// Get the dot product between the direction on entry to the bucket and the
// bucket surface normal
//
// Returns the dot product between the direction on entry to the bucket and the
// bucket surface normal
static G4double GetBucketCos() { return fsBucketCos; };
// Extract the history of a photon from its track.
void ExtractPhotonHistory(const G4FastTrack& fastTrack, RAT::DS::MCPE &photoelectron);
std::string fProcessName; // Process name, set by derived classes
G4int fMaxIterations; // Max iterations allowed in an optical model
G4double fSurfaceTolerance; // Distance required to ensure track does not reside on a surface
static G4int fsTrackID; // The current track ID
static G4int fsPMTID; // The current PMT ID
static G4double fsBucketCos; // The photon entry direction dot product with the bucket front surface normal
};
} //::RAT
#endif