Files
geant4/source/parameterisations/trd_clusters/src/G4PhotoClusterModel.cc
T
2016-06-09 11:11:55 +02:00

240 lines
7.4 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4PhotoClusterModel.cc,v 1.1 2004/11/09 09:20:34 hpw Exp $
// GEANT4 tag $Name: geant4-07-00-cand-01 $
//
#include "G4Timer.hh"
#include "G4PhotoClusterModel.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "globals.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4PhotoClusterModel::G4PhotoClusterModel(G4Envelope *anEnvelope) :
G4VClusterModel("G4PhotoClusterModel",anEnvelope)
{
fMatIndex = anEnvelope->GetMaterial()->GetIndex() ;
ComputePhotoAbsCof() ;
}
///////////////////////////////////////////////////////////////////////////
G4PhotoClusterModel::~G4PhotoClusterModel()
{
for(G4int i=0;i<fIntervalNumber;i++)
{
delete[] fPhotoAbsCof[i] ;
}
delete[] fPhotoAbsCof ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns condition for application of the model depending on particle type
G4bool G4PhotoClusterModel::IsApplicable(const G4ParticleDefinition& particle)
{
return &particle == G4Gamma::GammaDefinition() ;
}
/////////////////////////////////////////////////////////////////////
//
// UserTrigger() method: method which has to decide if
// the parameterisation has to be applied.
// Here ModelTrigger() asks the user (ie you) a 0/1 answer.
//
// Note that quantities like the local/global position/direction etc..
// are available at this level via the fastTrack parameter (allowing
// to check distance from boundaries, see below to allow the decision)
//
G4bool G4PhotoClusterModel::ModelTrigger(const G4FastTrack& fastTrack)
{
return ( fastTrack.GetPrimaryTrack()->GetKineticEnergy() > 1*keV &&
fastTrack.GetPrimaryTrack()->GetKineticEnergy() < 40*keV ) ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4PhotoClusterModel::DoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
G4double energy ;
G4double distance, lambda, step ;
G4ThreeVector clusterPosition ;
energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),direction) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*direction ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
// Cluster counting loop
lambda = 1.0/GetLinearPhotoAbs(energy) ;
step = RandExponential::shoot(lambda) ;
if(step > distance) // no change, return
{
return ;
}
else
{
G4ThreeVector globalStartPosition = fastTrack.GetPrimaryTrack()->
GetPosition() ;
G4ParticleMomentum globalDirection = fastTrack.GetPrimaryTrack()->
GetMomentumDirection() ;
// global (or local ?) cluster coordinates
// clusterPosition = fastTrack.GetPrimaryTrackLocalPosition() +
// stepSum*direction ;
clusterPosition = globalStartPosition + step*globalDirection ;
fClusterPositionVector.push_back(clusterPosition) ;
fClusterEnergyVector.push_back(energy) ;
fastStep.KillPrimaryTrack();
fastStep.SetPrimaryTrackPathLength(step);
fastStep.SetTotalEnergyDeposited(energy);
BuildDetectorResponse() ;
}
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Computes matrix of Sandia photo absorption cross section coefficients for
// G4Envelope material
void G4PhotoClusterModel::ComputePhotoAbsCof()
{
G4int i, j, numberOfElements ;
static const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4SandiaTable thisMaterialSandiaTable(fMatIndex) ;
numberOfElements = (*theMaterialTable)[fMatIndex]->GetNumberOfElements() ;
G4int* thisMaterialZ = new G4int[numberOfElements] ;
for(i=0;i<numberOfElements;i++)
{
thisMaterialZ[i] = (G4int)(*theMaterialTable)[fMatIndex]->
GetElement(i)->GetZ() ;
}
fIntervalNumber = thisMaterialSandiaTable.SandiaIntervals
(thisMaterialZ,numberOfElements) ;
fIntervalNumber = thisMaterialSandiaTable.SandiaMixing
( thisMaterialZ ,
(*theMaterialTable)[fMatIndex]->GetFractionVector() ,
numberOfElements,fIntervalNumber) ;
fPhotoAbsCof = new G4double*[fIntervalNumber] ;
for(i=0;i<fIntervalNumber;i++) fPhotoAbsCof[i] = new G4double[5] ;
for(i=0;i<fIntervalNumber;i++)
{
fPhotoAbsCof[i][0] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,0) ;
for(j=1;j<5;j++)
{
fPhotoAbsCof[i][j] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,j)*
(*theMaterialTable)[fMatIndex]->GetDensity() ;
}
}
delete[] thisMaterialZ ;
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Returns the value of linear photo absorption coefficient (in reciprocal
// length) for G4Envelope material
G4double G4PhotoClusterModel::GetLinearPhotoAbs(G4double omega)
{
G4int i ;
G4double omega2, omega3, omega4 ;
omega2 = omega*omega ;
omega3 = omega2*omega ;
omega4 = omega2*omega2 ;
for(i=0;i<fIntervalNumber;i++)
{
if( omega < fPhotoAbsCof[i][0] ) break ;
}
if( i == 0 )
{
G4Exception("Invalid (<I1) energy in G4PhotoClusterModel::GetLinearPhotoAbs");
}
else i-- ;
return fPhotoAbsCof[i][1]/omega + fPhotoAbsCof[i][2]/omega2 +
fPhotoAbsCof[i][3]/omega3 + fPhotoAbsCof[i][4]/omega4 ;
}
//
//
///////////////////////////////////////////////////////////////////////