Import Geant4 11.3.0 source tree
This commit is contained in:
@@ -6,6 +6,36 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-11-11 Gabriele Cosmo (fastsimchanneling-V11-02-04)
|
||||
- Fixed compilation warnings on macOS/XCode for implicit type conversions
|
||||
in G4CoherentPairProduction.
|
||||
|
||||
## 2024-10-22 Alexei Sytov (fastsimchanneling-V11-02-03)
|
||||
- Added new process G4CoherentPairProduction for the simulation
|
||||
of coherent pair production by high energy gamma in an oriented crystal.
|
||||
IMPORTANT: it works as a G4VDiscreteProcess, not as a parameterisation.
|
||||
IMPORTANT: it uses G4ChannelingFastSimCrystalData.
|
||||
- sources.cmake updated accordingly
|
||||
|
||||
## 2024-09-17 Vladimir Ivanchenko (fastsimchanneling-V11-02-02)
|
||||
- G4VChannelingFastSimCrystalData - fixed Coverity warning
|
||||
|
||||
## 2024-08-30 Alexei Sytov (fastsimchanneling-V11-02-01)
|
||||
- Considerable updates;
|
||||
- Semantic errors were corrected in G4BaierKatkov::RadIntegral and
|
||||
in G4VChannelingFastSimCrystalData::CoulombElectronScattering;
|
||||
- New model of ionization losses for e+- has been implemented ionization
|
||||
G4VChannelingFastSimCrystalData with some updates in
|
||||
G4ChannelingFastSimModel and G4ChannelingFastSimCrystalData;
|
||||
some bugs concerning particles of higher charges were corrected;
|
||||
- G4ChannelingFastSimCrystalData was updated to be compatible with
|
||||
new channeling dataset: G4CHANNELINGDATA. An option to use a custom
|
||||
input file was also added.
|
||||
- Some new get functions were added.
|
||||
|
||||
## 2024-07-17 Vladimir Ivanchenko (fastsimchanneling-V11-02-00)
|
||||
- G4VChannelingFastSimCrystalData - fixed Coverity warning
|
||||
|
||||
## 2023-10-23 Alexei Sytov (fastsimchanneling-V11-01-04)
|
||||
- G4Log replaced std::log
|
||||
- some small issues were fixed to comply with the Geant4 guidelines
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paterno (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of the Baier-Katkov integral:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
#ifndef G4BaierKatkov_h
|
||||
#define G4BaierKatkov_h 1
|
||||
|
||||
@@ -113,7 +117,7 @@ public:
|
||||
|
||||
///number of steps in a trajectory small piece before
|
||||
///the next call of the radiation integral
|
||||
void SetNSmallTrajectorySteps(G4double nSmallTrajectorySteps)
|
||||
void SetNSmallTrajectorySteps(G4int nSmallTrajectorySteps)
|
||||
{fNSmallTrajectorySteps = nSmallTrajectorySteps;}
|
||||
|
||||
///reinitialize intermediate integrals fFa, fSs, fSc, fSsx, fSsy, fScx, fScy;
|
||||
@@ -259,7 +263,7 @@ private:
|
||||
//in sampling, y-plane
|
||||
G4double fParamPhotonAngleY=1.e-3*CLHEP::rad; //a parameter radiated photon
|
||||
//sampling distribution, y-plane
|
||||
G4double fRadiationAngleFactor = 1.; // number of radiation angles 1/gamma:
|
||||
G4double fRadiationAngleFactor = 4.; // number of radiation angles 1/gamma:
|
||||
// more fRadiationAngleFactor =>
|
||||
// higher fParamPhotonAngleX and Y
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
|
||||
#ifndef G4ChannelingFastSimCrystalData_h
|
||||
#define G4ChannelingFastSimCrystalData_h 1
|
||||
@@ -60,7 +61,9 @@ public:
|
||||
|
||||
///find and upload crystal lattice input files, calculate all the basic values
|
||||
///(to do only once)
|
||||
void SetMaterialProperties(const G4Material* crystal, const G4String &lattice);
|
||||
void SetMaterialProperties(const G4Material* crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath);
|
||||
|
||||
///calculate the coordinates in the co-rotating reference system
|
||||
///within a channel (periodic cell)
|
||||
@@ -88,6 +91,10 @@ public:
|
||||
///auxialiary function to transform the horizontal angle
|
||||
G4double AngleXShift(G4double z){return fMiscutAngle + z*fCurv;}
|
||||
|
||||
///get channel width in x and y
|
||||
G4double GetChannelWidthX(){return fDx;}
|
||||
G4double GetChannelWidthY(){return fDy;}
|
||||
|
||||
private:
|
||||
|
||||
///variables
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
|
||||
#ifndef G4ChannelingFastSimInterpolation_h
|
||||
#define G4ChannelingFastSimInterpolation_h
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of channeling model:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
#ifndef G4ChannelingFastSimModel_h
|
||||
#define G4ChannelingFastSimModel_h 1
|
||||
@@ -63,7 +67,13 @@ public:
|
||||
void DoIt(const G4FastTrack&, G4FastStep&) override;
|
||||
|
||||
///special functions
|
||||
void Input(const G4Material* crystal, const G4String &lattice);
|
||||
void Input(const G4Material* crystal,
|
||||
const G4String &lattice)
|
||||
{Input(crystal,lattice,"");}
|
||||
|
||||
void Input(const G4Material* crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath);
|
||||
|
||||
void RadiationModelActivate();
|
||||
|
||||
@@ -80,11 +90,16 @@ public:
|
||||
void SetLindhardAngleNumberHighLimit(G4double angleNumber, const G4String& particleName)
|
||||
{fLindhardAngleNumberHighLimit[particleTable->FindParticle(particleName)->
|
||||
GetParticleDefinitionID()]=angleNumber;}
|
||||
void SetHighAngleLimit(G4double anglemax, const G4String& particleName)
|
||||
{fHighAngleLimit[particleTable->FindParticle(particleName)->
|
||||
GetParticleDefinitionID()] = anglemax;}
|
||||
|
||||
void SetDefaultLowKineticEnergyLimit(G4double ekinetic)
|
||||
{fDefaultLowEnergyLimit=ekinetic;}
|
||||
void SetDefaultLindhardAngleNumberHighLimit(G4double angleNumber)
|
||||
{fDefaultLindhardAngleNumberHighLimit=angleNumber;}
|
||||
void SetDefaultHighAngleLimit(G4double anglemax)
|
||||
{fDefaultHighAngleLimit=anglemax;}
|
||||
|
||||
|
||||
/// get the maximal number of photons that can be produced per fastStep
|
||||
@@ -93,15 +108,6 @@ public:
|
||||
{fMaxPhotonsProducedPerStep=nPhotons;}
|
||||
|
||||
///get cuts
|
||||
G4double GetLowKineticEnergyLimit(const G4String& particleName)
|
||||
{return GetLowKineticEnergyLimit(particleTable->
|
||||
FindParticle(particleName)->
|
||||
GetParticleDefinitionID());}
|
||||
G4double GetLindhardAngleNumberHighLimit(const G4String& particleName)
|
||||
{return GetLindhardAngleNumberHighLimit(particleTable->
|
||||
FindParticle(particleName)->
|
||||
GetParticleDefinitionID());}
|
||||
//the same functions but using particleDefinitionID (needed for faster model execution)
|
||||
G4double GetLowKineticEnergyLimit(G4int particleDefinitionID)
|
||||
{return (fLowEnergyLimit.count(particleDefinitionID) == 1)
|
||||
? fLowEnergyLimit[particleDefinitionID]
|
||||
@@ -110,6 +116,10 @@ public:
|
||||
{return (fLindhardAngleNumberHighLimit.count(particleDefinitionID) == 1)
|
||||
? fLindhardAngleNumberHighLimit[particleDefinitionID]
|
||||
: fDefaultLindhardAngleNumberHighLimit;}
|
||||
G4double GetHighAngleLimit(G4int particleDefinitionID)
|
||||
{return (fHighAngleLimit.count(particleDefinitionID) == 1)
|
||||
? fHighAngleLimit[particleDefinitionID]
|
||||
: fDefaultHighAngleLimit;}
|
||||
|
||||
/// get the maximal number of photons that can be produced per fastStep
|
||||
G4int GetMaxPhotonsProducedPerStep(){return fMaxPhotonsProducedPerStep;}
|
||||
@@ -124,12 +134,15 @@ private:
|
||||
///flag of radiation model
|
||||
G4bool fRad = false;
|
||||
|
||||
/// maps of cuts
|
||||
/// maps of cuts (angular cuts are chosen as std::max of
|
||||
/// fHighAngleLimit and calculated Lindhard angle)
|
||||
std::unordered_map<G4int, G4double> fLowEnergyLimit;
|
||||
std::unordered_map<G4int, G4double> fLindhardAngleNumberHighLimit;
|
||||
std::unordered_map<G4int, G4double> fHighAngleLimit;
|
||||
|
||||
G4double fDefaultLowEnergyLimit = 200*CLHEP::MeV;
|
||||
G4double fDefaultLindhardAngleNumberHighLimit = 100.;
|
||||
G4double fDefaultHighAngleLimit = 0.;
|
||||
|
||||
/// the maximal number of photons that can be produced per fastStep
|
||||
G4int fMaxPhotonsProducedPerStep=1000.;
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * 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. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paterno (testing)
|
||||
// Using the key points of G4BaierKatkov and developments of V.V. Tikhomirov,
|
||||
// partially described in L. Bandiera et al. Eur. Phys. J. C 82, 699 (2022)
|
||||
|
||||
#ifndef G4CoherentPairProduction_h
|
||||
#define G4CoherentPairProduction_h 1
|
||||
|
||||
#include "G4VDiscreteProcess.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <CLHEP/Units/SystemOfUnits.h>
|
||||
#include <CLHEP/Units/PhysicalConstants.h>
|
||||
#include <CLHEP/Vector/TwoVector.h>
|
||||
|
||||
#include "G4ChannelingFastSimCrystalData.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
class G4CoherentPairProduction : public G4VDiscreteProcess
|
||||
{
|
||||
public:
|
||||
G4CoherentPairProduction(const G4String& processName = "cpp",
|
||||
G4ProcessType aType = fElectromagnetic);
|
||||
|
||||
~G4CoherentPairProduction() = default;
|
||||
|
||||
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step&) override;
|
||||
|
||||
G4bool IsApplicable(const G4ParticleDefinition& aPD) override
|
||||
{
|
||||
return(aPD.GetParticleName() == "gamma");
|
||||
}
|
||||
|
||||
// print documentation in html format
|
||||
void ProcessDescription(std::ostream&) const override;
|
||||
|
||||
///special functions
|
||||
void Input(const G4Material* crystal,
|
||||
const G4String &lattice)
|
||||
{Input(crystal,lattice,"");}
|
||||
|
||||
void Input(const G4Material* crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath);
|
||||
|
||||
// an option to use crystal data already created outside this class
|
||||
void Input(const G4ChannelingFastSimCrystalData* crystalData);
|
||||
|
||||
///activate incoherent scattering
|
||||
///(standard gamma conversion should be switched off in physics list)
|
||||
void ActivateIncoherentScattering(){fIncoherentScattering = true;}
|
||||
|
||||
G4ChannelingFastSimCrystalData* GetCrystalData() {return fCrystalData;}
|
||||
|
||||
///get cuts
|
||||
// minimal energy for non-zero cross section
|
||||
G4double ModelMinPrimaryEnergy() { return fLowEnergyLimit;}
|
||||
G4double GetHighAngleLimit() {return fHighAngleLimit;}
|
||||
G4double GetPPKineticEnergyCut() {return fPPKineticEnergyCut;}
|
||||
|
||||
/// get the number of pairs in sampling of Baier-Katkov Integral
|
||||
/// (MC integration by e+- energy and angles <=> e+- momentum)
|
||||
G4int GetSamplingPairsNumber(){return fNMCPairs;}
|
||||
|
||||
/// get the number of particle angles 1/gamma in pair production
|
||||
/// defining the width of the angular distribution of pair sampling
|
||||
/// in the Baier-Katkov Integral
|
||||
G4double GetChargeParticleAngleFactor(){return fChargeParticleAngleFactor;}
|
||||
|
||||
/// get number of trajectory steps of a single particle (e- or e+)
|
||||
G4double GetNTrajectorySteps(){return fNTrajectorySteps;}
|
||||
|
||||
/// get effective radiation length
|
||||
/// (due to coherent process of pair production)
|
||||
/// simulated for the current photon
|
||||
G4double GetEffectiveLrad(){return fEffectiveLrad;}
|
||||
|
||||
///get the name of G4Region in which the model is applicable
|
||||
G4String GetG4RegionName() {return fG4RegionName;}
|
||||
|
||||
///set cuts
|
||||
void SetLowEnergyLimit(G4double energy){fLowEnergyLimit=energy;}
|
||||
void SetHighAngleLimit(G4double angle) {fHighAngleLimit=angle;}
|
||||
void SetPPKineticEnergyCut(G4double kineticEnergyCut) {fPPKineticEnergyCut=kineticEnergyCut;}
|
||||
|
||||
/// set the number of pairs in sampling of Baier-Katkov Integral
|
||||
/// (MC integration by e+- energy and angles <=> e+- momentum)
|
||||
void SetSamplingPairsNumber(G4int nPairs){fNMCPairs = nPairs;}
|
||||
|
||||
/// set the number of particle angles 1/gamma in pair production
|
||||
/// defining the width of the angular distribution of pair sampling
|
||||
/// in the Baier-Katkov Integral
|
||||
void SetChargeParticleAngleFactor(G4double chargeParticleAngleFactor)
|
||||
{fChargeParticleAngleFactor = chargeParticleAngleFactor;}
|
||||
|
||||
/// set number of trajectory steps of a single particle (e- or e+)
|
||||
void SetNTrajectorySteps(G4int nTrajectorySteps)
|
||||
{fNTrajectorySteps = nTrajectorySteps;}
|
||||
|
||||
///set the name of G4Region in which the model is applicable
|
||||
void SetG4RegionName(const G4String& nameG4Region){fG4RegionName=nameG4Region;}
|
||||
|
||||
G4double GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition* condition) override;
|
||||
|
||||
private:
|
||||
|
||||
G4int FindVectorIndex(std::vector<G4double> &myvector, G4double value);
|
||||
|
||||
G4ChannelingFastSimCrystalData* fCrystalData{nullptr};
|
||||
|
||||
//collection of etotal
|
||||
std::vector <CLHEP::Hep2Vector> fullVectorEtotal;
|
||||
|
||||
//collection of x
|
||||
std::vector <CLHEP::Hep2Vector> fullVectorX;
|
||||
|
||||
//collection of y
|
||||
std::vector <CLHEP::Hep2Vector> fullVectorY;
|
||||
|
||||
//collection of tx
|
||||
std::vector <CLHEP::Hep2Vector> fullVectorTX;
|
||||
|
||||
//collection of tx
|
||||
std::vector <CLHEP::Hep2Vector> fullVectorTY;
|
||||
|
||||
//the vector of the discrete CDF of the production of sampling e+e- pairs
|
||||
//(in reality per distance along the photon direction)
|
||||
std::vector <G4double> fPairProductionCDFdz;
|
||||
|
||||
G4double fLowEnergyLimit = 1*CLHEP::GeV;
|
||||
G4double fHighAngleLimit = 50*CLHEP::mrad;
|
||||
|
||||
///minimal kinetic energy of a charged particle produced
|
||||
G4double fPPKineticEnergyCut = 1*CLHEP::MeV;
|
||||
|
||||
///Monte Carlo statistics of e+- pair sampling in Baier-Katkov for 1 photon
|
||||
G4int fNMCPairs = 150;
|
||||
|
||||
G4double fChargeParticleAngleFactor = 4; // number of particle angles 1/gamma:
|
||||
// more fChargeParticleAngleFactor => higher paramParticleAngle
|
||||
|
||||
///number of trajectory steps of a single particle (e- or e+)
|
||||
G4int fNTrajectorySteps=250;
|
||||
|
||||
///effective radiation length (due to coherent process of pair production)
|
||||
G4double fEffectiveLrad = 0.;
|
||||
|
||||
///the name of G4Region in which the model is applicable
|
||||
G4String fG4RegionName = "Crystal";
|
||||
|
||||
///charged particle mass
|
||||
const G4double fMass = CLHEP::electron_mass_c2;
|
||||
|
||||
///flag of simulation of incoherent scattering
|
||||
G4bool fIncoherentScattering = false;
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of scattering model:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
#ifndef G4VChannelingFastSimCrystalData_h
|
||||
#define G4VChannelingFastSimCrystalData_h 1
|
||||
@@ -81,7 +84,7 @@ public:
|
||||
//don't put it =0, otherwise division on 0 in CoulombAtomicScattering
|
||||
|
||||
///Calculate the value of the Lindhard angle (!!! the value for a straight crystal)
|
||||
G4double GetLindhardAngle(G4double etotal, G4double mass);
|
||||
G4double GetLindhardAngle(G4double etotal, G4double mass, G4double charge);
|
||||
///Calculate the value of the Lindhard angle (!!! the value for a straight crystal)
|
||||
G4double GetLindhardAngle();//return the Lindhard angle value calculated in
|
||||
//SetParticleProperties
|
||||
@@ -90,7 +93,7 @@ public:
|
||||
///reduced value for overbarrier particles)
|
||||
G4double GetSimulationStep(G4double tx,G4double ty);
|
||||
///Calculate maximal simulation step (standard value for channeling particles)
|
||||
G4double GetMaxSimulationStep(G4double etotal, G4double mass);
|
||||
G4double GetMaxSimulationStep(G4double etotal, G4double mass, G4double charge);
|
||||
|
||||
///get particle velocity/c
|
||||
G4double GetBeta(){return fBeta;}
|
||||
@@ -119,7 +122,8 @@ public:
|
||||
///find and upload crystal lattice input files, calculate all the basic values
|
||||
///(to do only once)
|
||||
virtual void SetMaterialProperties(const G4Material* crystal,
|
||||
const G4String &lattice) = 0;
|
||||
const G4String &lattice,
|
||||
const G4String &filePath) = 0;
|
||||
|
||||
///set geometry parameters from current logical volume
|
||||
void SetGeometryParameters(const G4LogicalVolume *crystallogic);
|
||||
@@ -153,7 +157,7 @@ public:
|
||||
void SetParticleProperties(G4double etotal,
|
||||
G4double mp,
|
||||
G4double charge,
|
||||
G4bool ifhadron);
|
||||
const G4String& particleName);
|
||||
|
||||
///calculate the coordinates in the co-rotating reference system
|
||||
///within a channel (periodic cell)
|
||||
@@ -280,6 +284,7 @@ protected:
|
||||
G4double fK3=0;//a useful coefficient, fK3=2.*pi*alpha*hdc/electron_mass_c2/(fPV)**2
|
||||
|
||||
std::vector <G4double> fKD; //a useful coefficient for dE/dx
|
||||
std::vector <G4double> fLogPlasmaEdI0; //item of delta-correction of ionization loss
|
||||
|
||||
///coefficients for multiple scattering suppression
|
||||
std::vector <G4double> fPu11;//a useful coefficient for exponent containing u1
|
||||
@@ -324,7 +329,7 @@ private:
|
||||
G4double fTmax=0; // max ionization losses
|
||||
|
||||
///particle properties flags
|
||||
G4bool fHadron=false;//=true (for hadrons); =false (for leptons)
|
||||
G4String fParticleName = "";
|
||||
G4double fZ2=0; //particle charge
|
||||
|
||||
};
|
||||
|
||||
@@ -8,12 +8,14 @@ geant4_add_module(G4channeling
|
||||
G4ChannelingFastSimInterpolation.hh
|
||||
G4ChannelingFastSimModel.hh
|
||||
G4VChannelingFastSimCrystalData.hh
|
||||
G4CoherentPairProduction.hh
|
||||
SOURCES
|
||||
G4BaierKatkov.cc
|
||||
G4ChannelingFastSimCrystalData.cc
|
||||
G4ChannelingFastSimInterpolation.cc
|
||||
G4ChannelingFastSimModel.cc
|
||||
G4VChannelingFastSimCrystalData.cc)
|
||||
G4VChannelingFastSimCrystalData.cc
|
||||
G4CoherentPairProduction.cc)
|
||||
|
||||
geant4_module_link_libraries(G4channeling
|
||||
PUBLIC
|
||||
@@ -24,6 +26,9 @@ geant4_add_module(G4channeling
|
||||
G4parameterisation
|
||||
G4track
|
||||
G4partman
|
||||
G4procman
|
||||
PRIVATE
|
||||
G4bosons
|
||||
G4navigation)
|
||||
G4navigation
|
||||
G4leptons
|
||||
G4emutils)
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paterno (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of the Baier-Katkov integral:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
#include "G4BaierKatkov.hh"
|
||||
|
||||
@@ -446,7 +450,7 @@ G4double G4BaierKatkov::RadIntegral(G4double etotal, G4double mass,
|
||||
G4double coefNorm = CLHEP::fine_structure_const/(8*(CLHEP::pi2))*coefNormLogdNMC;
|
||||
G4double e2pluseprime2 = 0.;//e2pluseprime2 =e2+eprime2
|
||||
G4double coefNormom2deprime2 = 0.; //coefNormom2deprime2 = coefNorm*om2/eprime2;
|
||||
G4double gammaInverse2om = 0.; //gammaInverse2*om
|
||||
G4double gammaInverse2om2 = 0.; //gammaInverse2*om*om
|
||||
|
||||
std::size_t nmctotal = fPhotonEnergyInIntegral.size();
|
||||
for (std::size_t j=0;j<nmctotal;j++)
|
||||
@@ -459,7 +463,7 @@ G4double G4BaierKatkov::RadIntegral(G4double etotal, G4double mass,
|
||||
omprime=etotal*om/eprime;//om'=(E*om/E')
|
||||
omprimed2=omprime/2;
|
||||
coefNormom2deprime2 = coefNorm*om*om/eprime2;
|
||||
gammaInverse2om = gammaInverse2*om;
|
||||
gammaInverse2om2 = gammaInverse2*om*om;
|
||||
|
||||
for(std::size_t k=kmin;k<nparts;k++)
|
||||
{
|
||||
@@ -506,7 +510,7 @@ G4double G4BaierKatkov::RadIntegral(G4double etotal, G4double mass,
|
||||
|
||||
//updating the total radiation probability along the trajectory
|
||||
totalRadiationProbabilityPhj = coefNormom2deprime2*fPhotonAngleNormCoef[j]*
|
||||
(i2*e2pluseprime2+j2*gammaInverse2om);
|
||||
(i2*e2pluseprime2+j2*gammaInverse2om2);
|
||||
fTotalRadiationProbabilityAlongTrajectory[k] += totalRadiationProbabilityPhj;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
|
||||
#include "G4ChannelingFastSimCrystalData.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -35,8 +37,10 @@ G4ChannelingFastSimCrystalData::G4ChannelingFastSimCrystalData()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *crystal,
|
||||
const G4String &lattice)
|
||||
void G4ChannelingFastSimCrystalData::SetMaterialProperties(
|
||||
const G4Material *crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath)
|
||||
{
|
||||
G4String filename=crystal->GetName(); //input file
|
||||
filename.erase(0,3);
|
||||
@@ -46,9 +50,9 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *cry
|
||||
G4cout <<
|
||||
"======================================================================="
|
||||
<< G4endl;
|
||||
G4cout <<
|
||||
"====== Crystal lattice data ========"
|
||||
<< G4endl;
|
||||
G4cout <<
|
||||
"====== Crystal lattice data ========"
|
||||
<< G4endl;
|
||||
G4cout <<
|
||||
"======================================================================="
|
||||
<< G4endl;
|
||||
@@ -74,6 +78,18 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *cry
|
||||
//input file:
|
||||
filename = filename + lattice.substr(1,(lattice.length())-2) + ".dat";
|
||||
|
||||
if(filePath=="")
|
||||
{
|
||||
//standard file path if another one is not set
|
||||
filename = "/" + filename;
|
||||
filename = G4FindDataDir("G4CHANNELINGDATA") + filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
//custom file path
|
||||
filename = filePath + filename;
|
||||
}
|
||||
|
||||
fNelements=(G4int)crystal->GetNumberOfElements();
|
||||
for(G4int i=0; i<fNelements; i++)
|
||||
{
|
||||
@@ -87,6 +103,17 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *cry
|
||||
|
||||
std::ifstream vfilein;
|
||||
vfilein.open(filename);
|
||||
//check if the input file was found, otherwise return an exception
|
||||
if(!vfilein.is_open())
|
||||
{
|
||||
G4String outputMessage="Input file " +
|
||||
filename +
|
||||
" is not found!";
|
||||
G4Exception("SetMaterialProperties",
|
||||
"001",
|
||||
FatalException,
|
||||
outputMessage);
|
||||
}
|
||||
|
||||
//read nuclear concentration
|
||||
for(G4int i=0; i<fNelements; i++)
|
||||
@@ -275,6 +302,8 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *cry
|
||||
fK40.push_back(3.76*std::pow(CLHEP::fine_structure_const*fZ1[i],2.));
|
||||
|
||||
fKD.push_back(fK30*fZ1[i]*fN0[i]);
|
||||
|
||||
fLogPlasmaEdI0.push_back(G4Log((crystal->GetIonisation()->GetPlasmaEnergy())/fI0[i]));
|
||||
}
|
||||
|
||||
fBB.resize(fNelements);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
|
||||
/// \file G4ChannelingFastSimInterpolation.cc
|
||||
/// \brief Implementation of the G4ChannelingFastSimInterpolation class
|
||||
|
||||
@@ -23,7 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
/// \file B107FastSim/src/G4ChannelingFastSimModel.cc
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of channeling model:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
/// \file G4ChannelingFastSimModel.cc
|
||||
/// \brief Implementation of the G4ChannelingFastSimModel class
|
||||
//
|
||||
//
|
||||
@@ -101,12 +106,15 @@ G4bool G4ChannelingFastSimModel::ModelTrigger(const G4FastTrack& fastTrack)
|
||||
//particle mass
|
||||
G4double mass = fastTrack.GetPrimaryTrack()->GetParticleDefinition()->GetPDGMass();
|
||||
//particle total energy
|
||||
G4double etotal = fastTrack.GetPrimaryTrack()->GetTotalEnergy();
|
||||
G4double etotal = mass + ekinetic;
|
||||
//particle charge
|
||||
G4double charge = fastTrack.GetPrimaryTrack()->
|
||||
GetParticleDefinition()->GetPDGCharge();
|
||||
|
||||
//Particle position
|
||||
G4ThreeVector xyz0 = fastTrack.GetPrimaryTrackLocalPosition();
|
||||
//Step estimate
|
||||
G4double dz0 = fCrystalData->GetMaxSimulationStep(etotal,mass);
|
||||
G4double dz0 = fCrystalData->GetMaxSimulationStep(etotal,mass,charge);
|
||||
xyz0 += 2*dz0*momentumDirection;//overestimated particle shift on the next step
|
||||
//in channeling
|
||||
|
||||
@@ -117,8 +125,12 @@ G4bool G4ChannelingFastSimModel::ModelTrigger(const G4FastTrack& fastTrack)
|
||||
Inside(xyz0)==kInside) &&
|
||||
momentumDirection.z()>0. &&
|
||||
std::abs(angle) <
|
||||
GetLindhardAngleNumberHighLimit(particleDefinitionID) *
|
||||
fCrystalData->GetLindhardAngle(etotal,mass);
|
||||
std::max(
|
||||
GetLindhardAngleNumberHighLimit(particleDefinitionID) *
|
||||
fCrystalData->GetLindhardAngle(etotal,
|
||||
mass,
|
||||
charge),
|
||||
GetHighAngleLimit(particleDefinitionID));
|
||||
}
|
||||
|
||||
return modelTrigger;
|
||||
@@ -132,7 +144,10 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
G4double etotal;//particle total energy
|
||||
G4double etotalPreStep;//etotal at the previous step
|
||||
G4double etotalToSetParticleProperties;//etotal value at which
|
||||
//SetParticleProperties is called
|
||||
//SetParticleProperties is calculated
|
||||
G4double ekinetic = 0;//kinetic energy
|
||||
G4double eDeposited = 0.;//deposited energy along the trajectory
|
||||
G4double elossAccum = 0;// accumulate local energy loss (not radiation)
|
||||
G4double mass; //particle mass
|
||||
G4double charge;//particle charge
|
||||
G4double tGlobal; //global time
|
||||
@@ -151,6 +166,7 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
G4ThreeVector scatteringAnglesAndEnergyLoss;//output of scattering functions
|
||||
G4double lindhardAngleNumberHighLimit0; //current high limit of the angle expressed in
|
||||
//[Lindhard angle] units
|
||||
G4double highAngleLimit0; //current absolute high limit of the angle expressed
|
||||
|
||||
//coordinates in Runge-Kutta calculations
|
||||
G4double x1=0.,x2=0.,x3=0.,x4=0.,y1=0.,y2=0.,y3=0.,y4=0.;
|
||||
@@ -179,20 +195,21 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
fBaierKatkov->ResetRadIntegral();//to avoid any memory from the previous trajectory
|
||||
}
|
||||
|
||||
etotal = fastTrack.GetPrimaryTrack()->GetTotalEnergy();
|
||||
mass = fastTrack.GetPrimaryTrack()->GetParticleDefinition()->GetPDGMass();
|
||||
etotal = mass + fastTrack.GetPrimaryTrack()->GetKineticEnergy();
|
||||
charge = fastTrack.GetPrimaryTrack()->GetParticleDefinition()->GetPDGCharge();
|
||||
|
||||
// we need to distunguish only charge particles, either leptons or hadrons
|
||||
G4bool hadron =
|
||||
fastTrack.GetPrimaryTrack()->GetParticleDefinition()->GetLeptonNumber()==0;
|
||||
G4String particleName =
|
||||
fastTrack.GetPrimaryTrack()->GetParticleDefinition()->GetParticleName();
|
||||
|
||||
lindhardAngleNumberHighLimit0 =
|
||||
GetLindhardAngleNumberHighLimit(fastTrack.GetPrimaryTrack()->
|
||||
GetParticleDefinition()->GetParticleDefinitionID());
|
||||
highAngleLimit0 = GetHighAngleLimit(fastTrack.GetPrimaryTrack()->
|
||||
GetParticleDefinition()->GetParticleDefinitionID());
|
||||
|
||||
//set fCrystalData parameters depending on the particle parameters
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, hadron);
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, particleName);
|
||||
|
||||
//global time
|
||||
tGlobal = fastTrack.GetPrimaryTrack()->GetGlobalTime();
|
||||
@@ -324,7 +341,7 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
CoulombAtomicScattering(effectiveStep,momentumDirectionStep,i);
|
||||
|
||||
//Amorphous part of ionization energy losses
|
||||
etotal-=fCrystalData->IonizationLosses(momentumDirectionStep, i);
|
||||
elossAccum += fCrystalData->IonizationLosses(momentumDirectionStep, i);
|
||||
}
|
||||
//electron scattering and coherent part of ionization energy losses
|
||||
scatteringAnglesAndEnergyLoss += fCrystalData->CoulombElectronScattering(
|
||||
@@ -333,13 +350,13 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
momentumDirectionStep);
|
||||
tx += scatteringAnglesAndEnergyLoss.x();
|
||||
ty += scatteringAnglesAndEnergyLoss.y();
|
||||
etotal -= scatteringAnglesAndEnergyLoss.z();
|
||||
elossAccum += scatteringAnglesAndEnergyLoss.z();
|
||||
|
||||
// recalculate the energy depended parameters
|
||||
//(only if the energy decreased enough, not at each step)
|
||||
if (etotalToSetParticleProperties>etotal)
|
||||
{
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, hadron);
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, particleName);
|
||||
etotalToSetParticleProperties = etotal*0.999;
|
||||
}
|
||||
|
||||
@@ -359,14 +376,18 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
{
|
||||
//if the angle w.r.t. the planes is too high
|
||||
if (std::abs(tx) >=
|
||||
lindhardAngleNumberHighLimit0*fCrystalData->GetLindhardAngle())
|
||||
std::max(lindhardAngleNumberHighLimit0*
|
||||
fCrystalData->GetLindhardAngle(),
|
||||
highAngleLimit0))
|
||||
{inCrystal = false;}//escape the cycle
|
||||
}
|
||||
else if (fCrystalData->GetModel()==2) //2D model, field of axes
|
||||
{
|
||||
//if the angle w.r.t. the axes is too high
|
||||
if (std::sqrt(tx*tx+ty*ty) >= lindhardAngleNumberHighLimit0*
|
||||
fCrystalData->GetLindhardAngle())
|
||||
if (std::sqrt(tx*tx+ty*ty) >=
|
||||
std::max(lindhardAngleNumberHighLimit0*
|
||||
fCrystalData->GetLindhardAngle(),
|
||||
highAngleLimit0))
|
||||
{inCrystal = false;}//escape the cycle
|
||||
}
|
||||
|
||||
@@ -403,7 +424,7 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
fBaierKatkov->GeneratePhoton(fastStep);
|
||||
|
||||
//particle energy was changed
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, hadron);
|
||||
fCrystalData->SetParticleProperties(etotal, mass, charge, particleName);
|
||||
|
||||
//coordinates in the co-rotating reference system within a channel
|
||||
xyz = fCrystalData->CoordinatesFromBoxToLattice(xyz0);
|
||||
@@ -416,6 +437,25 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
ty = ty0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//we calculate deposited energy and energy losses ONLY in absence
|
||||
//of radiation otherwise we do it only at the end of model
|
||||
etotal -= elossAccum;
|
||||
eDeposited += elossAccum;
|
||||
elossAccum=0;
|
||||
ekinetic = etotal-mass;
|
||||
if(ekinetic<1*keV)
|
||||
{
|
||||
G4cout << "Warning in G4ChannelingFastSimModel: " <<
|
||||
ekinetic << "<" << 1*keV << " !" << G4endl;
|
||||
eDeposited-=(1*keV-ekinetic);
|
||||
ekinetic = 1*keV;
|
||||
G4cout << "Setting deposited energy=" <<
|
||||
eDeposited << " & ekinetic=" << ekinetic << G4endl;
|
||||
etotal = mass+ekinetic;
|
||||
}
|
||||
}
|
||||
|
||||
//precise check if the particle is escaping the volume
|
||||
if (crystallogic->GetSolid()->
|
||||
@@ -458,10 +498,25 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
fastStep.ProposePrimaryTrackFinalTime(tGlobal);
|
||||
//set final position
|
||||
fastStep.ProposePrimaryTrackFinalPosition(xyz0);
|
||||
|
||||
//set deposited energy (due to ionization)
|
||||
etotal -= elossAccum;
|
||||
eDeposited += elossAccum;
|
||||
ekinetic = etotal-mass;
|
||||
if(ekinetic<1*keV)
|
||||
{
|
||||
G4cout << "Warning in G4ChannelingFastSimModel: " <<
|
||||
ekinetic << "<" << 1*keV << " !" << G4endl;
|
||||
eDeposited-=(1*keV-ekinetic);
|
||||
ekinetic = 1*keV;
|
||||
G4cout << "Setting deposited energy=" <<
|
||||
eDeposited << " & ekinetic=" << ekinetic << G4endl;
|
||||
}
|
||||
fastStep.ProposeTotalEnergyDeposited(eDeposited);
|
||||
//set final kinetic energy
|
||||
fastStep.ProposePrimaryTrackFinalKineticEnergy(etotal-
|
||||
fastTrack.GetPrimaryTrack()->
|
||||
GetParticleDefinition()->GetPDGMass());
|
||||
fastStep.ProposePrimaryTrackFinalKineticEnergy(ekinetic);
|
||||
|
||||
|
||||
//set final momentum direction
|
||||
G4double momentumDirectionZ =
|
||||
1./std::sqrt(1.+std::pow(std::tan(tx0),2)+std::pow(std::tan(ty0),2));
|
||||
@@ -473,14 +528,16 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4ChannelingFastSimModel::Input(const G4Material *crystal, const G4String &lattice)
|
||||
void G4ChannelingFastSimModel::Input(const G4Material *crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath)
|
||||
{
|
||||
//initializing the class with containing all
|
||||
//the crystal material and crystal lattice data and
|
||||
//Channeling scattering and ionization processes
|
||||
fCrystalData = new G4ChannelingFastSimCrystalData();
|
||||
//setting all the crystal material and lattice data
|
||||
fCrystalData->SetMaterialProperties(crystal,lattice);
|
||||
fCrystalData->SetMaterialProperties(crystal,lattice,filePath);
|
||||
|
||||
//setting default low energy cuts for kinetic energy
|
||||
SetLowKineticEnergyLimit(1*GeV,"proton");
|
||||
|
||||
@@ -0,0 +1,692 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * 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. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paterno (testing)
|
||||
// Using the key points of G4BaierKatkov and developments of V.V. Tikhomirov,
|
||||
// partially described in L. Bandiera et al. Eur. Phys. J. C 82, 699 (2022)
|
||||
|
||||
#include "G4CoherentPairProduction.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4TouchableHistory.hh"
|
||||
#include "G4TouchableHandle.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
#include "G4Track.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4CoherentPairProduction::G4CoherentPairProduction(const G4String& aName,
|
||||
G4ProcessType):
|
||||
G4VDiscreteProcess(aName)
|
||||
{
|
||||
SetProcessSubType(fCoherentPairProduction);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4CoherentPairProduction::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
//current logical volume
|
||||
G4LogicalVolume* crystallogic;
|
||||
|
||||
//momentum direction and coordinates (see comments below)
|
||||
G4ThreeVector momentumDirectionGamma,xyzGamma0,xyzGamma;
|
||||
//angle of the photon in the local reference system of the volume
|
||||
G4double txGamma0 = 0, tyGamma0 = 0;
|
||||
|
||||
*condition = NotForced;
|
||||
|
||||
//model activation
|
||||
G4bool modelTrigger = false;
|
||||
|
||||
//photon energy
|
||||
G4double eGamma = aTrack.GetTotalEnergy();
|
||||
|
||||
//energy cut, at the beginning, to not check everything else
|
||||
if(eGamma > ModelMinPrimaryEnergy())
|
||||
{
|
||||
//current logical volume
|
||||
crystallogic = aTrack.GetVolume()->GetLogicalVolume();
|
||||
|
||||
//the model works only in the G4Region fG4RegionName
|
||||
if(crystallogic->GetRegion()->GetName()==fG4RegionName)
|
||||
{
|
||||
fCrystalData->SetGeometryParameters(crystallogic);
|
||||
|
||||
//the momentum direction of the photon in the local reference system of the volume
|
||||
momentumDirectionGamma =
|
||||
(aTrack.GetTouchableHandle()->GetHistory()->
|
||||
GetTopTransform().NetRotation().inverse())*aTrack.GetMomentumDirection();
|
||||
|
||||
//the coordinates of the photon in the local reference system of the volume
|
||||
xyzGamma0 =
|
||||
aTrack.GetTouchableHandle()->GetHistory()->
|
||||
GetTopTransform().TransformPoint(aTrack.GetPosition());
|
||||
|
||||
// the coordinates of the photon in the co-rotating reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
xyzGamma = fCrystalData->CoordinatesFromBoxToLattice(xyzGamma0);
|
||||
|
||||
//angle of the photon in the local reference system of the volume
|
||||
//(!!! ONLY FORWARD DIRECTION, momentumDirectionGamma.getZ()>0,
|
||||
txGamma0 = std::atan(momentumDirectionGamma.x()/momentumDirectionGamma.z());
|
||||
tyGamma0 = std::atan(momentumDirectionGamma.y()/momentumDirectionGamma.z());
|
||||
|
||||
//recalculate angle into the lattice reference system
|
||||
G4double angle = fCrystalData->AngleXFromBoxToLattice(txGamma0,xyzGamma.z());
|
||||
if (fCrystalData->GetModel()==2)
|
||||
{
|
||||
angle = std::sqrt(angle*angle+tyGamma0*tyGamma0);
|
||||
}
|
||||
|
||||
//Applies the parameterisation not at the last step, only forward local direction
|
||||
//above low energy limit and below angular limit
|
||||
modelTrigger = (momentumDirectionGamma.z()>0. &&
|
||||
std::abs(angle) < GetHighAngleLimit());
|
||||
}
|
||||
}
|
||||
|
||||
if(modelTrigger)
|
||||
{
|
||||
//execute the model
|
||||
|
||||
G4double x=0.,y=0.,z=0.;// the coordinates of charged particles
|
||||
//in the co-rotating reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
G4double tx0=0.,ty0=0.; // the angles of charged particles
|
||||
// in the local reference system of the volume
|
||||
G4double txPreStep0=0.,tyPreStep0=0.; // the same as tx0, ty0 before the step
|
||||
// in the co-rotating reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
|
||||
G4ThreeVector scatteringAnglesAndEnergyLoss;//output of scattering functions
|
||||
|
||||
//coordinates in Runge-Kutta calculations
|
||||
G4double x1=0.,x2=0.,x3=0.,x4=0.,y1=0.,y2=0.,y3=0.,y4=0.;
|
||||
//angles in Runge-Kutta calculations
|
||||
G4double tx1=0.,tx2=0.,tx3=0.,tx4=0.,ty1=0.,ty2=0.,ty3=0.,ty4=0.;
|
||||
//variables in Runge-Kutta calculations
|
||||
G4double kvx1=0.,kvx2=0.,kvx3=0.,kvx4=0.,kvy1=0.,kvy2=0.,kvy3=0.,kvy4=0.;
|
||||
//simulation step along z (internal step of the model) and its parts
|
||||
G4double dz=0.,dzd3=0.,dzd8=0.;//dzd3 = dz/3; dzd8 = dz/8;
|
||||
//simulation step along the momentum direction
|
||||
G4double momentumDirectionStep;
|
||||
//effective simulation step (taking into account nuclear density along the trajectory)
|
||||
G4double effectiveStep=0.;
|
||||
|
||||
// Baier-Katkov variables
|
||||
G4double dzMeV=0.; //step in MeV^-1
|
||||
G4double axt=0.,ayt=0.; //charged particle accelerations
|
||||
G4double vxin=0.,vyin=0.;//the angles vs the photon (with incoherent scattering)
|
||||
G4double vxno=0.,vyno=0.;//the angles vs the photon (without incoherent scattering)
|
||||
|
||||
G4double dzmod=0.;
|
||||
G4double fa1=0.,faseBefore=0.,faseBeforedz=0.,faseBeforedzd2=0.;
|
||||
G4double faseAfter=0.,fa2dfaseBefore2=0.;
|
||||
|
||||
G4double skJ=0, skIx=0., skIy=0.;
|
||||
G4double sinfa1=0.,cosfa1=0.;
|
||||
|
||||
//2-vector is needed for an initial parameter collection of 1 pair
|
||||
//vector of 2-vectors is an initial parameter collection of all sampling pair
|
||||
|
||||
//collection of etotal for a single pair
|
||||
CLHEP::Hep2Vector twoVectorEtotal(0.,0.);
|
||||
|
||||
//collection of x for a single pair
|
||||
CLHEP::Hep2Vector twoVectorX(0.,0.);
|
||||
|
||||
//collection of y for a single pair
|
||||
CLHEP::Hep2Vector twoVectorY(0.,0.);
|
||||
|
||||
//collection of tx for a single pair
|
||||
CLHEP::Hep2Vector twoVectorTX(0.,0.);
|
||||
|
||||
//collection of tx for a single pair
|
||||
CLHEP::Hep2Vector twoVectorTY(0.,0.);
|
||||
|
||||
fullVectorEtotal.clear();
|
||||
fullVectorX.clear();
|
||||
fullVectorY.clear();
|
||||
fullVectorTX.clear();
|
||||
fullVectorTY.clear();
|
||||
fPairProductionCDFdz.clear();
|
||||
fPairProductionCDFdz.push_back(0.);//0th element equal to 0
|
||||
|
||||
const G4double charge[2] = {-1.,1.}; //particle charge
|
||||
const G4String particleName[2] = {"e-", "e+"};
|
||||
|
||||
// the coordinates of a charged particle in the reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
G4ThreeVector xyzparticle = xyzGamma;//changed below
|
||||
|
||||
//the idea of pair production simulation is analogical to radiation in G4BaierKatkov
|
||||
//since the matrix element of these processes is the same => we solve inverse problem
|
||||
//to radiation: sample the pairs, calculate their trajectories and then calculate the
|
||||
//probabilities using Baier-Katkov analogically to radiation
|
||||
|
||||
//cycle by sampling e+- pairs
|
||||
for(G4int i=0; i<fNMCPairs;i++)
|
||||
{
|
||||
//pair energy uniform sampling
|
||||
G4double etotal = fMass + fPPKineticEnergyCut +
|
||||
G4UniformRand()*(eGamma-2*(fMass+fPPKineticEnergyCut));//particle
|
||||
//total energy
|
||||
|
||||
G4double phi = CLHEP::twopi*G4UniformRand();//necessary for pair kinematics
|
||||
|
||||
//the probability of the production of the current pair (will be simulated)
|
||||
//per distance
|
||||
G4double probabilityPPdz = 0.;
|
||||
|
||||
//cycle e- and e+ within single pair
|
||||
for(G4int j=0; j<2;j++)
|
||||
{
|
||||
if(j==1){etotal=eGamma-etotal;} //2nd particle energy
|
||||
twoVectorEtotal[j]=etotal;
|
||||
|
||||
//Baier-Katkov input
|
||||
//intermediate variables to reduce calculations (the same names as in G4BaierKatkov)
|
||||
G4double e2 = etotal*etotal;
|
||||
G4double gammaInverse2 = fMass*fMass/(etotal*etotal);// 1/gamma^2
|
||||
//normalization coefficient
|
||||
G4double coefNorm = CLHEP::fine_structure_const/(8*(CLHEP::pi2))/(2.*fNMCPairs);
|
||||
//G4double phi = CLHEP::twopi*G4UniformRand();//necessary for pair kinematics
|
||||
G4double om = eGamma;
|
||||
G4double eprime=om-etotal; //E'=omega-E
|
||||
G4double eprime2 = eprime*eprime;
|
||||
G4double e2pluseprime2 =e2+eprime2;
|
||||
G4double omprime=etotal*om/eprime;//om'=E*om/(om-E)
|
||||
G4double omprimed2=omprime/2;
|
||||
|
||||
//difference vs G4BaierKatkov: om -> etotal
|
||||
G4double coefNorme2deprime2 = coefNorm*e2/eprime2; //e2/om/om;//e2/eprime2;
|
||||
|
||||
G4double gammaInverse2om = gammaInverse2*om*om;
|
||||
|
||||
//initialize intermediate integrals with zeros
|
||||
G4double fa=0.,ss=0.,sc=0.,ssx=0.,ssy=0.,scx=0.,scy=0.;
|
||||
|
||||
//End of Baier-Katkov input
|
||||
|
||||
G4bool fbreak = false;//flag of the trajectory cycle break
|
||||
|
||||
//set fCrystalData parameters depending on the particle parameters
|
||||
fCrystalData->SetParticleProperties(etotal, fMass,
|
||||
charge[j], particleName[j]);
|
||||
|
||||
//needed just to setup the correct value of channel No in the crystal
|
||||
//since later it may be changed during the trajectory calculation
|
||||
fCrystalData->CoordinatesFromBoxToLattice(xyzGamma0);
|
||||
|
||||
//coordinate sampling: random x and y due to coordinate uncertainty
|
||||
//in the interaction point
|
||||
if(j==0)
|
||||
{
|
||||
x = fCrystalData->GetChannelWidthX()*G4UniformRand();
|
||||
y = fCrystalData->GetChannelWidthY()*G4UniformRand();
|
||||
}
|
||||
else
|
||||
{
|
||||
x=twoVectorX[0];
|
||||
y=twoVectorY[0];
|
||||
}
|
||||
twoVectorX[j] = x;
|
||||
twoVectorY[j] = y;
|
||||
//definite z as a coordinate of the photon (uncertainty of the
|
||||
//interaction point is taking into account later by simulation
|
||||
//of the position of pair production)
|
||||
z = xyzGamma.z();
|
||||
|
||||
//angles of the photon in the co-rotating reference system within a channel =>
|
||||
//angular distribution center
|
||||
G4double tx = fCrystalData->AngleXFromBoxToLattice(txGamma0,z);
|
||||
G4double ty = tyGamma0;
|
||||
G4double momentumDirectionZGamma = 1./
|
||||
std::sqrt(1.+std::pow(std::tan(tx),2)+
|
||||
std::pow(std::tan(ty),2));
|
||||
|
||||
//angle sampling: depends on angular range within a particle trajectory
|
||||
//defined by the Lindhard angle and on the angle of radiation proportional
|
||||
//to 1/gamma
|
||||
|
||||
//range of MC integration on angles
|
||||
G4double paramParticleAngle = fChargeParticleAngleFactor*fMass/etotal;
|
||||
|
||||
G4double axangle=0.;
|
||||
if (fCrystalData->GetModel()==1)//1D model (only angle vs plane matters)
|
||||
{
|
||||
axangle = std::abs(tx);
|
||||
}
|
||||
else if (fCrystalData->GetModel()==2)//2D model
|
||||
{
|
||||
axangle = std::sqrt(tx*tx+ty*ty);
|
||||
}
|
||||
|
||||
if(axangle>fCrystalData->GetLindhardAngle()+DBL_EPSILON)
|
||||
{
|
||||
paramParticleAngle+=axangle
|
||||
-std::sqrt(axangle*axangle
|
||||
-fCrystalData->GetLindhardAngle()
|
||||
*fCrystalData->GetLindhardAngle());
|
||||
}
|
||||
else
|
||||
{
|
||||
paramParticleAngle+=fCrystalData->GetLindhardAngle();
|
||||
}
|
||||
|
||||
|
||||
//ONLY forward direction
|
||||
if (paramParticleAngle>CLHEP::halfpi-DBL_EPSILON){paramParticleAngle=CLHEP::halfpi;}
|
||||
|
||||
G4double rho=1.;
|
||||
G4double rhocut=CLHEP::halfpi/paramParticleAngle;//radial angular cut of
|
||||
//the distribution
|
||||
G4double norm=std::atan(rhocut*rhocut)*
|
||||
CLHEP::pi*paramParticleAngle*paramParticleAngle;
|
||||
|
||||
|
||||
//distribution with long tails (useful to not exclude particle angles
|
||||
//after a strong single scattering)
|
||||
//at ellipsescale < 1 => half of statistics
|
||||
do
|
||||
{
|
||||
rho = std::sqrt(std::tan(CLHEP::halfpi*G4UniformRand()));
|
||||
}
|
||||
while (rho>rhocut);
|
||||
|
||||
//normalization coefficient for intergration on angles of charged particles
|
||||
G4double angleNormCoef = (1.+rho*rho*rho*rho)*norm;
|
||||
|
||||
tx+=charge[j]*paramParticleAngle*rho*std::cos(phi);
|
||||
twoVectorTX[j] = tx;
|
||||
ty+=charge[j]*paramParticleAngle*rho*std::sin(phi);
|
||||
twoVectorTY[j] = ty;
|
||||
|
||||
G4double zalongGamma = 0;//necessary for renormalization of PP probability
|
||||
//depending on the trajectory length along Gamma direction
|
||||
//starting the trajectory
|
||||
//here we don't care about the boundaries of the crystal volume
|
||||
//the trajectory is very short and the pair production probability obtained
|
||||
//in Baier-Katkov will be extrapolated to the real step inside the crystal volume
|
||||
for(G4int k=0; k<fNTrajectorySteps;k++)
|
||||
{
|
||||
//back to the local reference system of the volume
|
||||
txPreStep0 = fCrystalData->AngleXFromLatticeToBox(tx,z);
|
||||
tyPreStep0 = ty;
|
||||
|
||||
dz = fCrystalData->GetSimulationStep(tx,ty);
|
||||
dzd3=dz/3;
|
||||
dzd8=dz/8;
|
||||
|
||||
//trajectory calculation:
|
||||
//Runge-Cutt "3/8"
|
||||
//fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ() is due to dependence
|
||||
//of the radius on x; GetCurv gets 1/R for the central ("central plane/axis")
|
||||
|
||||
//first step
|
||||
kvx1=fCrystalData->Ex(x,y);
|
||||
x1=x+tx*dzd3;
|
||||
tx1=tx+(kvx1-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dzd3;
|
||||
if (fCrystalData->GetModel()==2)
|
||||
{
|
||||
kvy1=fCrystalData->Ey(x,y);
|
||||
y1=y+ty*dzd3;
|
||||
ty1=ty+kvy1*dzd3;
|
||||
}
|
||||
|
||||
//second step
|
||||
kvx2=fCrystalData->Ex(x1,y1);
|
||||
x2=x-tx*dzd3+tx1*dz;
|
||||
tx2=tx-(kvx1-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dzd3+
|
||||
(kvx2-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dz;
|
||||
if (fCrystalData->GetModel()==2)
|
||||
{
|
||||
kvy2=fCrystalData->Ey(x1,y1);
|
||||
y2=y-ty*dzd3+ty1*dz;
|
||||
ty2=ty-kvy1*dzd3+kvy2*dz;
|
||||
}
|
||||
|
||||
//third step
|
||||
kvx3=fCrystalData->Ex(x2,y2);
|
||||
x3=x+(tx-tx1+tx2)*dz;
|
||||
tx3=tx+(kvx1-kvx2+kvx3-
|
||||
fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dz;
|
||||
if (fCrystalData->GetModel()==2)
|
||||
{
|
||||
kvy3=fCrystalData->Ey(x2,y2);
|
||||
y3=y+(ty-ty1+ty2)*dz;
|
||||
ty3=ty+(kvy1-kvy2+kvy3)*dz;
|
||||
}
|
||||
|
||||
//fourth step
|
||||
kvx4=fCrystalData->Ex(x3,y3);
|
||||
x4=x+(tx+3.*tx1+3.*tx2+tx3)*dzd8;
|
||||
tx4=tx+(kvx1+3.*kvx2+3.*kvx3+kvx4)*dzd8-
|
||||
fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ()*dz;
|
||||
if (fCrystalData->GetModel()==2)
|
||||
{
|
||||
kvy4=fCrystalData->Ey(x3,y3);
|
||||
y4=y+(ty+3.*ty1+3.*ty2+ty3)*dzd8;
|
||||
ty4=ty+(kvy1+3.*kvy2+3.*kvy3+kvy4)*dzd8;
|
||||
}
|
||||
else
|
||||
{
|
||||
y4 =y+ty*dz;
|
||||
ty4=ty;
|
||||
}
|
||||
|
||||
x=x4;
|
||||
tx=tx4;
|
||||
y=y4;
|
||||
ty=ty4;
|
||||
|
||||
z+=dz*fCrystalData->GetCorrectionZ();//motion along the z coordinate
|
||||
//("central plane/axis", no current plane/axis)
|
||||
|
||||
xyzparticle = fCrystalData->ChannelChange(x,y,z);
|
||||
x=xyzparticle.x();
|
||||
y=xyzparticle.y();
|
||||
z=xyzparticle.z();
|
||||
|
||||
momentumDirectionStep =
|
||||
dz*std::sqrt(1+std::pow(std::tan(tx),2)+std::pow(std::tan(ty),2));
|
||||
zalongGamma += dz/momentumDirectionZGamma;
|
||||
|
||||
//default scattering and energy loss 0
|
||||
scatteringAnglesAndEnergyLoss.set(0.,0.,0.);
|
||||
|
||||
if(fIncoherentScattering)
|
||||
{
|
||||
//calculate separately for each element of the crystal
|
||||
for (G4int ii = 0; ii < fCrystalData->GetNelements(); ii++)
|
||||
{
|
||||
//effective step taking into account nuclear density along the trajectory
|
||||
effectiveStep = momentumDirectionStep*
|
||||
fCrystalData->NuclearDensity(x,y,ii);
|
||||
//Coulomb scattering on screened atomic potential
|
||||
//(both multiple and single)
|
||||
scatteringAnglesAndEnergyLoss +=
|
||||
fCrystalData->CoulombAtomicScattering(effectiveStep,
|
||||
momentumDirectionStep,
|
||||
ii);
|
||||
}
|
||||
//electron scattering and coherent part of ionization energy losses
|
||||
scatteringAnglesAndEnergyLoss += fCrystalData->CoulombElectronScattering(
|
||||
fCrystalData->MinIonizationEnergy(x,y),
|
||||
fCrystalData->ElectronDensity(x,y),
|
||||
momentumDirectionStep);
|
||||
tx += scatteringAnglesAndEnergyLoss.x();
|
||||
ty += scatteringAnglesAndEnergyLoss.y();
|
||||
}
|
||||
|
||||
//To avoid backward direction
|
||||
if(std::abs(tx)>CLHEP::halfpi-DBL_EPSILON||
|
||||
std::abs(ty)>CLHEP::halfpi-DBL_EPSILON)
|
||||
{
|
||||
G4cout << "Warning: particle angle is beyond +-pi/2 range => "
|
||||
"skipping the calculation of its probability" << G4endl;
|
||||
fbreak = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//**********Baier-Katkov start
|
||||
|
||||
//back to the local reference system of the volume
|
||||
tx0 = fCrystalData->AngleXFromLatticeToBox(tx,z);
|
||||
ty0 = ty;
|
||||
|
||||
dzMeV=momentumDirectionStep/CLHEP::hbarc;// in MeV^-1
|
||||
|
||||
// accelerations
|
||||
axt=(tx0-scatteringAnglesAndEnergyLoss.x()-txPreStep0)/dzMeV;
|
||||
ayt=(ty0-scatteringAnglesAndEnergyLoss.y()-tyPreStep0)/dzMeV;
|
||||
|
||||
//the angles vs the photon (with incoherent scattering)
|
||||
vxin = tx0-txGamma0;
|
||||
vyin = ty0-tyGamma0;
|
||||
//the angles vs the photon (without incoherent scattering)
|
||||
vxno = vxin-scatteringAnglesAndEnergyLoss.x();
|
||||
vyno = vyin-scatteringAnglesAndEnergyLoss.y();
|
||||
|
||||
//phase difference before scattering
|
||||
faseBefore=omprimed2*(gammaInverse2+vxno*vxno+vyno*vyno);//phi' t<ti//MeV
|
||||
|
||||
faseBeforedz = faseBefore*dzMeV;
|
||||
faseBeforedzd2 = faseBeforedz/2.;
|
||||
fa+=faseBeforedz; //
|
||||
fa1=fa-faseBeforedzd2;//
|
||||
dzmod=2*std::sin(faseBeforedzd2)/faseBefore;//MeV^-1
|
||||
|
||||
//phi''/faseBefore^2
|
||||
fa2dfaseBefore2 = omprime*(axt*vxno+ayt*vyno)/(faseBefore*faseBefore);
|
||||
|
||||
//phase difference after scattering
|
||||
faseAfter=omprimed2*(gammaInverse2+vxin*vxin+vyin*vyin);//phi' ti+O//MeV
|
||||
|
||||
skJ=1/faseAfter-1/faseBefore-fa2dfaseBefore2*dzmod;//MeV^-1
|
||||
skIx=vxin/faseAfter-vxno/faseBefore+dzmod*(axt/faseBefore-
|
||||
vxno*fa2dfaseBefore2);
|
||||
skIy=vyin/faseAfter-vyno/faseBefore+dzmod*(ayt/faseBefore-
|
||||
vyno*fa2dfaseBefore2);
|
||||
|
||||
sinfa1 = std::sin(fa1);
|
||||
cosfa1 = std::cos(fa1);
|
||||
|
||||
ss+=sinfa1*skJ;//sum sin integral J of BK
|
||||
sc+=cosfa1*skJ;//sum cos integral J of BK
|
||||
ssx+=sinfa1*skIx;// sum sin integral Ix of BK
|
||||
ssy+=sinfa1*skIy;// sum sin integral Iy of BK
|
||||
scx+=cosfa1*skIx;// sum cos integral Ix of BK
|
||||
scy+=cosfa1*skIy;// sum cos integral Iy of BK
|
||||
}
|
||||
|
||||
//only of the trajectory cycle was not broken
|
||||
if(!fbreak)
|
||||
{
|
||||
G4double i2=ssx*ssx+scx*scx+ssy*ssy+scy*scy;//MeV^-2
|
||||
G4double j2=ss*ss+sc*sc;//MeV^-2
|
||||
|
||||
probabilityPPdz += coefNorme2deprime2*angleNormCoef*
|
||||
(i2*e2pluseprime2+j2*gammaInverse2om)/zalongGamma;
|
||||
}
|
||||
}
|
||||
|
||||
//filling the CDF of probabilities of the production of sampling pairs
|
||||
fPairProductionCDFdz.push_back(fPairProductionCDFdz[i]+probabilityPPdz);
|
||||
//**********Baier-Katkov end
|
||||
|
||||
//accumulation of initial parameters of sampling pairs
|
||||
fullVectorEtotal.push_back(twoVectorEtotal);
|
||||
fullVectorX.push_back(twoVectorX);
|
||||
fullVectorY.push_back(twoVectorY);
|
||||
fullVectorTX.push_back(twoVectorTX);
|
||||
fullVectorTY.push_back(twoVectorTY);
|
||||
}
|
||||
|
||||
//photon mean free path
|
||||
//fPairProductionCDFdz.back() = full pair production probability
|
||||
//simulated for the current photon along photon direction
|
||||
G4double lMeanFreePath = 1/fPairProductionCDFdz.back();
|
||||
|
||||
fEffectiveLrad = 7.*lMeanFreePath/9.;//only for scoring purpose
|
||||
|
||||
return lMeanFreePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
//dummy process, does not occur
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4CoherentPairProduction::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
//example with no physical sense
|
||||
aParticleChange.Initialize(aTrack);
|
||||
//G4LogicalVolume* aLV = aTrack.GetVolume()->GetLogicalVolume();
|
||||
|
||||
const G4ParticleDefinition* chargedParticleDefinition[2] =
|
||||
{G4Electron::Electron(),G4Positron::Positron()};
|
||||
|
||||
// the coordinates of the photon in the local reference system of the volume
|
||||
G4ThreeVector xyzGamma0 =
|
||||
aTrack.GetTouchableHandle()->GetHistory()->
|
||||
GetTopTransform().TransformPoint(aTrack.GetPosition());
|
||||
|
||||
// the coordinates of the photon in the co-rotating reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
G4ThreeVector xyzGamma = fCrystalData->CoordinatesFromBoxToLattice(xyzGamma0);
|
||||
|
||||
//global time
|
||||
G4double tGlobalGamma = aTrack.GetGlobalTime();
|
||||
|
||||
G4double ksi1 = G4UniformRand()*fPairProductionCDFdz.back();
|
||||
|
||||
//randomly choosing the pair to be produced from the sampling list
|
||||
//according to the probabilities calculated in the Baier-Katkov integral
|
||||
G4int ipair = FindVectorIndex(fPairProductionCDFdz,ksi1)-1;//index of
|
||||
//a pair produced
|
||||
|
||||
// the coordinates of a charged particle in the reference system within
|
||||
//a channel (elementary periodic cell)
|
||||
G4ThreeVector xyzparticle;
|
||||
//cycle e- and e+ within single pair
|
||||
for(G4int j=0; j<2;j++)
|
||||
{
|
||||
xyzparticle.set(fullVectorX[ipair][j],fullVectorY[ipair][j],xyzGamma.z());
|
||||
|
||||
//in the local reference system of the volume
|
||||
G4ThreeVector newParticleCoordinateXYZ =
|
||||
fCrystalData->CoordinatesFromLatticeToBox(xyzparticle);
|
||||
//the same in the global reference system
|
||||
newParticleCoordinateXYZ =
|
||||
aTrack.GetTouchableHandle()->GetHistory()->
|
||||
GetTopTransform().Inverse().TransformPoint(newParticleCoordinateXYZ);
|
||||
|
||||
//back to the local reference system of the volume
|
||||
G4double tx0 = fCrystalData->AngleXFromLatticeToBox(fullVectorTX[ipair][j],xyzGamma.z());
|
||||
G4double ty0 = fullVectorTY[ipair][j];
|
||||
|
||||
G4double momentumDirectionZ = 1./
|
||||
std::sqrt(1.+std::pow(std::tan(tx0),2)+
|
||||
std::pow(std::tan(ty0),2));
|
||||
|
||||
//momentum direction vector of the charged particle produced
|
||||
//in the local reference system of the volume
|
||||
G4ThreeVector momentumDirectionParticle = G4ThreeVector(momentumDirectionZ*std::tan(tx0),
|
||||
momentumDirectionZ*std::tan(ty0),
|
||||
momentumDirectionZ);
|
||||
//the same in the global reference system
|
||||
momentumDirectionParticle =
|
||||
(aTrack.GetTouchableHandle()->GetHistory()->GetTopTransform().NetRotation()) *
|
||||
momentumDirectionParticle;
|
||||
|
||||
G4DynamicParticle* chargedParticle =
|
||||
new G4DynamicParticle(chargedParticleDefinition[j],
|
||||
momentumDirectionParticle,
|
||||
fullVectorEtotal[ipair][j]-fMass);
|
||||
|
||||
// Create the track for the secondary particle
|
||||
G4Track* secondaryTrack = new G4Track(chargedParticle,
|
||||
tGlobalGamma,
|
||||
newParticleCoordinateXYZ);
|
||||
secondaryTrack->SetTouchableHandle(aStep.GetPostStepPoint()->GetTouchableHandle());
|
||||
secondaryTrack->SetParentID(aTrack.GetTrackID());
|
||||
|
||||
//generation of a secondary charged particle
|
||||
aParticleChange.AddSecondary(secondaryTrack);
|
||||
}
|
||||
|
||||
//killing the photon
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4CoherentPairProduction::FindVectorIndex(std::vector<G4double> &myvector, G4double value)
|
||||
{
|
||||
auto iteratorbegin = myvector.begin();
|
||||
auto iteratorend = myvector.end();
|
||||
|
||||
//vector index (for non precise values lower_bound gives upper value)
|
||||
auto loweriterator = std::lower_bound(iteratorbegin, iteratorend, value);
|
||||
//return the index of the vector element
|
||||
return (G4int)std::distance(iteratorbegin, loweriterator);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4CoherentPairProduction::Input(const G4Material *crystal,
|
||||
const G4String &lattice,
|
||||
const G4String &filePath)
|
||||
{
|
||||
//initializing the class with containing all
|
||||
//the crystal material and crystal lattice data and
|
||||
//Channeling scattering and ionization processes
|
||||
fCrystalData = new G4ChannelingFastSimCrystalData();
|
||||
//setting all the crystal material and lattice data
|
||||
fCrystalData->SetMaterialProperties(crystal,lattice,filePath);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4CoherentPairProduction::Input(const G4ChannelingFastSimCrystalData *crystalData)
|
||||
{
|
||||
//setting the class with containing all
|
||||
//the crystal material and crystal lattice data and
|
||||
//Channeling scattering and ionization processes
|
||||
//fCrystalData = new G4ChannelingFastSimCrystalData();
|
||||
|
||||
fCrystalData = const_cast<G4ChannelingFastSimCrystalData*>(crystalData);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4CoherentPairProduction::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << " Coherent pair production";
|
||||
G4VDiscreteProcess::ProcessDescription(out);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -23,6 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Alexei Sytov
|
||||
// Co-author: Gianfranco Paternò (modifications & testing)
|
||||
// On the base of the CRYSTALRAD realization of scattering model:
|
||||
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
|
||||
|
||||
#include "G4VChannelingFastSimCrystalData.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -210,19 +214,19 @@ void G4VChannelingFastSimCrystalData::SetCUParameters(
|
||||
void G4VChannelingFastSimCrystalData::SetParticleProperties(G4double etotal,
|
||||
G4double mass,
|
||||
G4double charge,
|
||||
G4bool ifhadron)
|
||||
const G4String& particleName)
|
||||
{
|
||||
G4double teta1;
|
||||
fZ2=charge;
|
||||
G4double zz22=fZ2*fZ2;
|
||||
fHadron=ifhadron;
|
||||
fParticleName=particleName;
|
||||
|
||||
// particle momentum and energy
|
||||
G4double t=etotal*etotal-mass*mass; // economy of operations
|
||||
fPz=std::sqrt(t); // momentum of particle
|
||||
fPV=t/etotal; // pv
|
||||
fBeta=fPz/etotal; // velocity/c
|
||||
fTetaL = std::sqrt(fVmax2/fPV); //Lindhard angle
|
||||
fTetaL = std::sqrt(std::abs(fZ2)*fVmax2/fPV); //Lindhard angle
|
||||
fChannelingStep = fChangeStep/fTetaL; //standard simulation step
|
||||
|
||||
// Energy losses
|
||||
@@ -233,6 +237,8 @@ void G4VChannelingFastSimCrystalData::SetParticleProperties(G4double etotal,
|
||||
fTmax = fMe2Gamma*fGamma*fV2/
|
||||
(CLHEP::electron_mass_c2/mass*CLHEP::electron_mass_c2/mass +
|
||||
1. + fMe2Gamma/mass);
|
||||
// max ionization losses for electrons
|
||||
if(fParticleName=="e-"){fTmax/=2;}
|
||||
|
||||
for(G4int i=0; i<fNelements; i++)
|
||||
{
|
||||
@@ -262,24 +268,23 @@ void G4VChannelingFastSimCrystalData::SetParticleProperties(G4double etotal,
|
||||
fTetamax2[i]=tetamax*tetamax;
|
||||
fTetamax12[i]=fTeta12[i]+fTetamax2[i];
|
||||
|
||||
// a cofficient in a formula for scattering (for high speed of simulation)
|
||||
// fK2=(fZ2*alpha*hdc)**2*4.*pi*fN0*(fZ1/fPV)**2
|
||||
// fK3=(fZ2*alpha*hdc)**2*4.*pi*fN0/(fPV)**2
|
||||
// a coefficient in a formula for scattering (for high speed of simulation)
|
||||
// fK2=(fZ2)**2*alphahbarc2*4.*pi*fN0*(fZ1/fPV)**2
|
||||
fK2[i]=fK20[i]*zz22/fPV/fPV;
|
||||
}
|
||||
|
||||
// nuclear diffractive scattering angle
|
||||
//tetaQEL=1./sqrt(2.*(9.26-4.94/sqrt(fPz/GeV)+0.28*log(fPz/GeV)));
|
||||
|
||||
fK3=fK30/fV2;
|
||||
// fK3=(fZ2)**2*alphahbarc2*pi/electron_mass_c2/(fV2)**2
|
||||
fK3=fK30*zz22/fV2;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VChannelingFastSimCrystalData::GetLindhardAngle(G4double etotal, G4double mass)
|
||||
G4double G4VChannelingFastSimCrystalData::GetLindhardAngle(G4double etotal,
|
||||
G4double mass,
|
||||
G4double charge)
|
||||
{
|
||||
G4double pv0 = etotal-mass*mass/etotal;
|
||||
return std::sqrt(2*fVmax/pv0); //Calculate the value of the Lindhard angle
|
||||
return std::sqrt(2*std::abs(charge)*fVmax/pv0); //Calculate the value of the Lindhard angle
|
||||
//(!!! the value for a straight crystal)
|
||||
}
|
||||
|
||||
@@ -313,7 +318,8 @@ G4double G4VChannelingFastSimCrystalData::GetSimulationStep(G4double tx,G4double
|
||||
}
|
||||
else
|
||||
{
|
||||
simulationstep = fChangeStep/angle;
|
||||
simulationstep = fChangeStep;
|
||||
if (angle > 0.0) { simulationstep /= angle; }
|
||||
}
|
||||
|
||||
return simulationstep;
|
||||
@@ -322,10 +328,11 @@ G4double G4VChannelingFastSimCrystalData::GetSimulationStep(G4double tx,G4double
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VChannelingFastSimCrystalData::GetMaxSimulationStep(G4double etotal,
|
||||
G4double mass)
|
||||
G4double mass,
|
||||
G4double charge)
|
||||
{
|
||||
//standard value of step for channeling particles which is the maximal possible step
|
||||
return fChangeStep/GetLindhardAngle(etotal, mass);
|
||||
return fChangeStep/GetLindhardAngle(etotal, mass, charge);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -479,11 +486,14 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombElectronScattering(
|
||||
G4double e1=eMinIonization/(1.-ksi*(1.-eMinIonization/fTmax));
|
||||
|
||||
// scattering angle
|
||||
G4double t=std::sqrt(e1*(e1+2.*CLHEP::electron_mass_c2))/fPz;
|
||||
G4double t=0;
|
||||
if(fTmax-e1>DBL_EPSILON) //to be sure e1<fTmax
|
||||
{
|
||||
t=std::sqrt(2.*CLHEP::electron_mass_c2*e1*(1-e1/fTmax))/fPz;
|
||||
}
|
||||
|
||||
// energy losses
|
||||
if (fHadron) {eloss=e1;} // we don't calculate ionization losses for e+-
|
||||
|
||||
eloss=e1;
|
||||
ksi=G4UniformRand();
|
||||
|
||||
tx+=t*std::cos(CLHEP::twopi*ksi);
|
||||
@@ -507,11 +517,33 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombElectronScattering(
|
||||
G4double G4VChannelingFastSimCrystalData::IonizationLosses(G4double dz,
|
||||
G4int ielement)
|
||||
{
|
||||
//amorphous part of ionization losses
|
||||
|
||||
G4double elosses = 0.;
|
||||
if (fHadron) {elosses=fKD[ielement]/fV2*
|
||||
(G4Log(fMe2Gamma*fV2/fI0[ielement]/fGamma) - fV2)*dz;}
|
||||
return elosses;
|
||||
}
|
||||
// 1/2 already taken into account in fKD
|
||||
|
||||
G4double loge = G4Log(fMe2Gamma*fGamma*fV2/fI0[ielement]);
|
||||
G4double delta= 2*(G4Log(fBeta*fGamma)+fLogPlasmaEdI0[ielement]-0.5);
|
||||
if(delta<0){delta=0;}
|
||||
loge-=delta;
|
||||
if(fParticleName=="e-")
|
||||
{
|
||||
loge+=(-G4Log(2.) + 1
|
||||
-(2*fGamma - 1)/fGamma/fGamma*G4Log(2.) +
|
||||
1/8*((fGamma - 1)/fGamma)*((fGamma - 1)/fGamma));
|
||||
}
|
||||
else if(fParticleName=="e+")
|
||||
{
|
||||
loge+=(-fV2/12*(11 + 14/(fGamma + 1) + 10/(fGamma + 1)/(fGamma + 1) +
|
||||
4/(fGamma + 1)/(fGamma + 1)/(fGamma + 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
loge-=fV2;
|
||||
}
|
||||
elosses=fZ2*fZ2*fKD[ielement]/fV2*loge*dz;
|
||||
|
||||
return elosses;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -6,6 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2024-10-21 Igor Semeniouk (gflash-V11-02-01)
|
||||
- GFlashSamplingShowerParameterisation - add GetEffDensity function
|
||||
- correction of Es and sampling resolution function
|
||||
- Rossi approximation for Ec added as comment
|
||||
|
||||
## 2024-09-10 Igor Semeniouk (gflash-V11-02-00)
|
||||
- clang-format for the files in parametrisation/gflash
|
||||
|
||||
## 2023-10-19 Ben Morgan (gflash-V11-01-01)
|
||||
- Replace use of deprecated functions with modern equivalents
|
||||
|
||||
|
||||
@@ -47,26 +47,26 @@
|
||||
class G4GFlashSpot
|
||||
{
|
||||
public:
|
||||
G4GFlashSpot(const GFlashEnergySpot* aSpot, const G4FastTrack* aTrack, G4TouchableHandle aH)
|
||||
: theSpot(aSpot), theTrack(aTrack), theHandle(aH)
|
||||
{}
|
||||
|
||||
G4GFlashSpot(const GFlashEnergySpot * aSpot,
|
||||
const G4FastTrack * aTrack, G4TouchableHandle aH)
|
||||
: theSpot(aSpot), theTrack(aTrack), theHandle(aH) {}
|
||||
|
||||
~G4GFlashSpot() {}
|
||||
|
||||
const GFlashEnergySpot * GetEnergySpot() const {return theSpot;}
|
||||
|
||||
const G4FastTrack * GetOriginatorTrack() const {return theTrack;}
|
||||
|
||||
G4TouchableHandle GetTouchableHandle() const {return theHandle;}
|
||||
|
||||
|
||||
const GFlashEnergySpot* GetEnergySpot() const { return theSpot; }
|
||||
|
||||
const G4FastTrack* GetOriginatorTrack() const { return theTrack; }
|
||||
|
||||
G4TouchableHandle GetTouchableHandle() const { return theHandle; }
|
||||
|
||||
G4ThreeVector GetPosition() const
|
||||
{return GetOriginatorTrack()->GetPrimaryTrack()->GetPosition();}
|
||||
|
||||
{
|
||||
return GetOriginatorTrack()->GetPrimaryTrack()->GetPosition();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const GFlashEnergySpot * theSpot;
|
||||
const G4FastTrack * theTrack;
|
||||
const GFlashEnergySpot* theSpot;
|
||||
const G4FastTrack* theTrack;
|
||||
G4TouchableHandle theHandle;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,81 +48,66 @@
|
||||
#include "G4GFlashSpot.hh"
|
||||
#include "G4VSensitiveDetector.hh"
|
||||
|
||||
|
||||
class G4VGFlashSensitiveDetector
|
||||
class G4VGFlashSensitiveDetector
|
||||
{
|
||||
public: // with description
|
||||
G4VGFlashSensitiveDetector() {}
|
||||
G4VGFlashSensitiveDetector(const G4VGFlashSensitiveDetector&) {}
|
||||
// Constructors. The user's concrete class must use one of these
|
||||
// constructors by the constructor initializer of the derived class.
|
||||
// The name of the sensitive detector must be the same as for the
|
||||
// corresponding GG4VSensitiveDetector.
|
||||
|
||||
public: // with description
|
||||
public: // without description
|
||||
virtual ~G4VGFlashSensitiveDetector() {}
|
||||
|
||||
G4VGFlashSensitiveDetector() {}
|
||||
G4VGFlashSensitiveDetector(const G4VGFlashSensitiveDetector &) {}
|
||||
// Constructors. The user's concrete class must use one of these
|
||||
// constructors by the constructor initializer of the derived class.
|
||||
// The name of the sensitive detector must be the same as for the
|
||||
// corresponding GG4VSensitiveDetector.
|
||||
G4bool operator==(const G4VGFlashSensitiveDetector& right) const { return this == &right; }
|
||||
G4bool operator!=(const G4VGFlashSensitiveDetector& right) const { return this != &right; }
|
||||
|
||||
public: // without description
|
||||
public: // without description
|
||||
inline G4bool Hit(G4GFlashSpot* aSpot)
|
||||
{
|
||||
// This is the public method invoked by GFlashHitMaker for generating
|
||||
// hits. The actual user's implementation for generating hits must be
|
||||
// implemented in GenerateHits() virtual protected method.
|
||||
|
||||
virtual ~G4VGFlashSensitiveDetector() {}
|
||||
|
||||
G4bool operator==(const G4VGFlashSensitiveDetector &right) const
|
||||
{return this == &right;}
|
||||
G4bool operator!=(const G4VGFlashSensitiveDetector &right) const
|
||||
{return this != &right;}
|
||||
|
||||
public: // without description
|
||||
|
||||
inline G4bool Hit(G4GFlashSpot * aSpot)
|
||||
{
|
||||
// This is the public method invoked by GFlashHitMaker for generating
|
||||
// hits. The actual user's implementation for generating hits must be
|
||||
// implemented in GenerateHits() virtual protected method.
|
||||
|
||||
G4bool result = true;
|
||||
G4VSensitiveDetector * This
|
||||
= dynamic_cast<G4VSensitiveDetector *>(this);
|
||||
if(!This)
|
||||
{
|
||||
G4Exception("G4VGFlashSensitiveDetector::Hit()",
|
||||
"InvalidSetup", FatalException,
|
||||
"Needs also to inherit from G4VSensitiveDetector!");
|
||||
return false;
|
||||
}
|
||||
if(This->isActive())
|
||||
{
|
||||
G4VReadOutGeometry * ROgeometry = 0;
|
||||
G4TouchableHistory* ROhis = 0;
|
||||
|
||||
if(This) ROgeometry = This->GetROgeometry();
|
||||
if(ROgeometry)
|
||||
{
|
||||
// fake pre-step point for touchable from read-out geometry.
|
||||
G4Step fakeStep;
|
||||
G4StepPoint * tmpPoint = fakeStep.GetPreStepPoint();
|
||||
tmpPoint->SetTouchableHandle(aSpot->GetTouchableHandle());
|
||||
tmpPoint->SetPosition(aSpot->GetPosition());
|
||||
tmpPoint->SetMomentumDirection(aSpot->GetOriginatorTrack()
|
||||
->GetPrimaryTrack()->GetMomentumDirection());
|
||||
result = ROgeometry->CheckROVolume(&fakeStep, ROhis);
|
||||
}
|
||||
if(result) result = ProcessHits(aSpot, ROhis);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
G4bool result = true;
|
||||
G4VSensitiveDetector* This = dynamic_cast<G4VSensitiveDetector*>(this);
|
||||
if (!This) {
|
||||
G4Exception("G4VGFlashSensitiveDetector::Hit()", "InvalidSetup", FatalException,
|
||||
"Needs also to inherit from G4VSensitiveDetector!");
|
||||
return false;
|
||||
}
|
||||
if (This->isActive()) {
|
||||
G4VReadOutGeometry* ROgeometry = 0;
|
||||
G4TouchableHistory* ROhis = 0;
|
||||
|
||||
protected: // with description
|
||||
if (This) ROgeometry = This->GetROgeometry();
|
||||
if (ROgeometry) {
|
||||
// fake pre-step point for touchable from read-out geometry.
|
||||
G4Step fakeStep;
|
||||
G4StepPoint* tmpPoint = fakeStep.GetPreStepPoint();
|
||||
tmpPoint->SetTouchableHandle(aSpot->GetTouchableHandle());
|
||||
tmpPoint->SetPosition(aSpot->GetPosition());
|
||||
tmpPoint->SetMomentumDirection(
|
||||
aSpot->GetOriginatorTrack()->GetPrimaryTrack()->GetMomentumDirection());
|
||||
result = ROgeometry->CheckROVolume(&fakeStep, ROhis);
|
||||
}
|
||||
if (result) result = ProcessHits(aSpot, ROhis);
|
||||
}
|
||||
else {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual G4bool ProcessHits(G4GFlashSpot*aSpot,
|
||||
G4TouchableHistory*ROhist) = 0;
|
||||
// The user MUST implement this method for generating hit(s) from the
|
||||
// GFlashSpots. Be aware that this method is a protected method and it
|
||||
// will be invoked by Hit() method of the Base class once the Readout
|
||||
// geometry that may be associated to the corresponding
|
||||
// G4VSensitiveDetector was taken into account.
|
||||
protected: // with description
|
||||
virtual G4bool ProcessHits(G4GFlashSpot* aSpot, G4TouchableHistory* ROhist) = 0;
|
||||
// The user MUST implement this method for generating hit(s) from the
|
||||
// GFlashSpots. Be aware that this method is a protected method and it
|
||||
// will be invoked by Hit() method of the Base class once the Readout
|
||||
// geometry that may be associated to the corresponding
|
||||
// G4VSensitiveDetector was taken into account.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,21 +46,19 @@
|
||||
class GFlashEnergySpot
|
||||
{
|
||||
public:
|
||||
|
||||
GFlashEnergySpot();
|
||||
GFlashEnergySpot(const G4ThreeVector& point, G4double E);
|
||||
~GFlashEnergySpot();
|
||||
|
||||
inline void SetEnergy(const G4double& E) {Energy = E;}
|
||||
inline G4double GetEnergy() const {return Energy;}
|
||||
|
||||
inline void SetPosition(const G4ThreeVector& point) {Point = point;}
|
||||
inline G4ThreeVector GetPosition() const {return Point;}
|
||||
|
||||
private:
|
||||
|
||||
G4double Energy; // energy deposition
|
||||
G4ThreeVector Point; // locus of energy deposition
|
||||
inline void SetEnergy(const G4double& E) { Energy = E; }
|
||||
inline G4double GetEnergy() const { return Energy; }
|
||||
|
||||
inline void SetPosition(const G4ThreeVector& point) { Point = point; }
|
||||
inline G4ThreeVector GetPosition() const { return Point; }
|
||||
|
||||
private:
|
||||
G4double Energy; // energy deposition
|
||||
G4ThreeVector Point; // locus of energy deposition
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -52,22 +52,20 @@ class G4Step;
|
||||
class G4StepPoint;
|
||||
class G4VProcess;
|
||||
|
||||
class GFlashHitMaker
|
||||
class GFlashHitMaker
|
||||
{
|
||||
public:
|
||||
|
||||
GFlashHitMaker();
|
||||
~GFlashHitMaker();
|
||||
|
||||
void make(GFlashEnergySpot * aSpot, const G4FastTrack * aT );
|
||||
inline void SetNameOfWorldWithSD(const G4String& aName) {fWorldWithSdName = aName;};
|
||||
|
||||
|
||||
void make(GFlashEnergySpot* aSpot, const G4FastTrack* aT);
|
||||
inline void SetNameOfWorldWithSD(const G4String& aName) { fWorldWithSdName = aName; };
|
||||
|
||||
inline void SetProcess(G4VProcess* proc) { fpProcess = proc; }
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
G4TouchableHandle fTouchableHandle;
|
||||
G4Navigator *fpNavigator;
|
||||
G4Navigator* fpNavigator;
|
||||
G4bool fNaviSetup;
|
||||
/// Name of the world containing the sensitive detector. If empty, default mass world is used.
|
||||
G4String fWorldWithSdName;
|
||||
@@ -77,12 +75,7 @@ class GFlashHitMaker
|
||||
G4VProcess* fpProcess = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
GFlashHitMaker(const GFlashHitMaker & ) {}
|
||||
GFlashHitMaker & operator = (const GFlashHitMaker & )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
GFlashHitMaker(const GFlashHitMaker&) {}
|
||||
GFlashHitMaker& operator=(const GFlashHitMaker&) { return *this; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -49,13 +49,11 @@ class G4Material;
|
||||
class GFlashHomoShowerParameterisation : public GVFlashShowerParameterisation
|
||||
{
|
||||
public: // with description
|
||||
|
||||
GFlashHomoShowerParameterisation(G4Material * aMat,
|
||||
GVFlashHomoShowerTuning * aPar = 0);
|
||||
GFlashHomoShowerParameterisation(G4Material* aMat, GVFlashHomoShowerTuning* aPar = 0);
|
||||
~GFlashHomoShowerParameterisation();
|
||||
|
||||
void ComputeRadialParameters(G4double y, G4double Tau);
|
||||
void GenerateLongitudinalProfile(G4double Energy);
|
||||
void GenerateLongitudinalProfile(G4double Energy);
|
||||
void ComputeZAX0EFFetc();
|
||||
|
||||
G4double IntegrateEneLongitudinal(G4double LongitudinalStep);
|
||||
@@ -63,71 +61,69 @@ class GFlashHomoShowerParameterisation : public GVFlashShowerParameterisation
|
||||
G4double ComputeTau(G4double LongitudinalPosition);
|
||||
|
||||
G4double GeneratePhi();
|
||||
G4double GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition);
|
||||
G4double GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition);
|
||||
G4double GenerateExponential(G4double Energy);
|
||||
void SetMaterial(G4Material *mat);
|
||||
void SetMaterial(G4Material* mat);
|
||||
|
||||
inline G4double GetAveR99() {return (3.5 * Rm);}
|
||||
inline G4double GetAveR90() {return (1.5 * Rm);} //ok
|
||||
inline G4double GetAveR99() { return (3.5 * Rm); }
|
||||
inline G4double GetAveR90() { return (1.5 * Rm); } // ok
|
||||
|
||||
inline G4double GetAveTmx() {return (X0 * std::exp(AveLogTmaxh));}
|
||||
inline G4double GetAveT99() {return (X0 * AveLogTmaxh/(AveLogAlphah-1.00));}
|
||||
inline G4double GetAveT90() {return (2.5* X0*std::exp( AveLogTmaxh) );}
|
||||
|
||||
inline G4double GetNspot(){ return NSpot;}
|
||||
inline G4double GetX0(){return X0;}
|
||||
inline G4double GetEc(){return Ec;}
|
||||
inline G4double GetRm(){return Rm;}
|
||||
inline G4double GetX0() { return X0; }
|
||||
inline G4double GetEc() { return Ec; }
|
||||
inline G4double GetRm() { return Rm; }
|
||||
|
||||
private:
|
||||
G4Material* material;
|
||||
|
||||
G4Material *material;
|
||||
|
||||
//Resolution
|
||||
G4double ConstantResolution;
|
||||
G4double NoiseResolution;
|
||||
// Resolution
|
||||
G4double ConstantResolution;
|
||||
G4double NoiseResolution;
|
||||
G4double SamplingResolution;
|
||||
|
||||
// parametrization parameters
|
||||
GVFlashHomoShowerTuning * thePar;
|
||||
GVFlashHomoShowerTuning* thePar;
|
||||
|
||||
// Cashed parameters:
|
||||
// Cashed parameters:
|
||||
// Longitudinal Coefficients for a homogeneous calo
|
||||
G4double ParAveT1;
|
||||
G4double ParAveA1,ParAveA2,ParAveA3;
|
||||
G4double ParSigLogT1,ParSigLogT2;
|
||||
G4double ParSigLogA1,ParSigLogA2;
|
||||
G4double ParRho1,ParRho2;
|
||||
G4double ParAveA1, ParAveA2, ParAveA3;
|
||||
G4double ParSigLogT1, ParSigLogT2;
|
||||
G4double ParSigLogA1, ParSigLogA2;
|
||||
G4double ParRho1, ParRho2;
|
||||
|
||||
void ComputeLongitudinalParameters(G4double y);
|
||||
void GenerateEnergyProfile(G4double y);
|
||||
void GenerateNSpotProfile(G4double y);
|
||||
|
||||
// Radial Coefficients
|
||||
G4double ParRC1,ParRC2,ParRC3,ParRC4;
|
||||
G4double ParWC1,ParWC2,ParWC3;
|
||||
G4double ParWC4,ParWC5,ParWC6;
|
||||
G4double ParRT1,ParRT2,ParRT3,ParRT4;
|
||||
G4double ParRT5,ParRT6;
|
||||
G4double ParRC1, ParRC2, ParRC3, ParRC4;
|
||||
G4double ParWC1, ParWC2, ParWC3;
|
||||
G4double ParWC4, ParWC5, ParWC6;
|
||||
G4double ParRT1, ParRT2, ParRT3, ParRT4;
|
||||
G4double ParRT5, ParRT6;
|
||||
|
||||
// Spot multiplicity Coefficients
|
||||
G4double ParSpotT1,ParSpotT2,ParSpotA1, ParSpotA2;
|
||||
G4double ParSpotN1,ParSpotN2;
|
||||
G4double ParSpotT1, ParSpotT2, ParSpotA1, ParSpotA2;
|
||||
G4double ParSpotN1, ParSpotN2;
|
||||
|
||||
// PARAMETRISATION variables (Energy & position dependent)
|
||||
// Longitudinal
|
||||
// Longitudinal
|
||||
// homogeneous
|
||||
G4double AveLogAlphah,AveLogTmaxh;
|
||||
G4double SigmaLogAlphah,SigmaLogTmaxh;
|
||||
G4double AveLogAlphah, AveLogTmaxh;
|
||||
G4double SigmaLogAlphah, SigmaLogTmaxh;
|
||||
G4double Rhoh;
|
||||
G4double Alphah,Tmaxh,Betah;
|
||||
G4double Alphah, Tmaxh, Betah;
|
||||
|
||||
// Multiplicity
|
||||
G4double NSpot,AlphaNSpot,TNSpot,BetaNSpot;
|
||||
G4double NSpot, AlphaNSpot, TNSpot, BetaNSpot;
|
||||
|
||||
//Radial
|
||||
G4double RadiusCore, WeightCore,RadiusTail;
|
||||
// Radial
|
||||
G4double RadiusCore, WeightCore, RadiusTail;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,36 +39,30 @@
|
||||
// Author: Joanna Weng - 9.11.04
|
||||
//---------------------------------------------------------------
|
||||
#ifndef GFlashParticleBounds_h
|
||||
#define GFlashParticleBounds_h
|
||||
#define GFlashParticleBounds_h
|
||||
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
class GFlashParticleBounds
|
||||
class GFlashParticleBounds
|
||||
{
|
||||
public: // with description
|
||||
|
||||
GFlashParticleBounds();
|
||||
~GFlashParticleBounds();
|
||||
|
||||
|
||||
// methods to get/set ELE/Gamma max & min energy bounds
|
||||
|
||||
G4double GetMinEneToParametrise(G4ParticleDefinition &particleType);
|
||||
G4double GetMaxEneToParametrise(G4ParticleDefinition &particleType);
|
||||
G4double GetEneToKill(G4ParticleDefinition &particleType) ;
|
||||
|
||||
void SetMinEneToParametrise(G4ParticleDefinition &particleType,
|
||||
G4double enemin);
|
||||
void SetMaxEneToParametrise(G4ParticleDefinition &particleType,
|
||||
G4double enemax);
|
||||
void SetEneToKill(G4ParticleDefinition &particleType,
|
||||
G4double enekill);
|
||||
G4double GetMinEneToParametrise(G4ParticleDefinition& particleType);
|
||||
G4double GetMaxEneToParametrise(G4ParticleDefinition& particleType);
|
||||
G4double GetEneToKill(G4ParticleDefinition& particleType);
|
||||
|
||||
void SetMinEneToParametrise(G4ParticleDefinition& particleType, G4double enemin);
|
||||
void SetMaxEneToParametrise(G4ParticleDefinition& particleType, G4double enemax);
|
||||
void SetEneToKill(G4ParticleDefinition& particleType, G4double enekill);
|
||||
|
||||
private:
|
||||
|
||||
// electron and positron
|
||||
G4double EMinEneToParametrise;
|
||||
G4double EMaxEneToParametrise;
|
||||
G4double EEneToKill;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,130 +46,127 @@
|
||||
|
||||
class G4Material;
|
||||
|
||||
class GFlashSamplingShowerParameterisation
|
||||
: public GVFlashShowerParameterisation
|
||||
class GFlashSamplingShowerParameterisation : public GVFlashShowerParameterisation
|
||||
{
|
||||
public:
|
||||
GFlashSamplingShowerParameterisation(
|
||||
G4Material* aMat1, G4Material* aMat2, G4double d1, G4double d2,
|
||||
/// \param aMat1 passive material, \param dd1 - passive layer thickness
|
||||
/// \param aMat2 active material, \param dd2 - acive layer thickness
|
||||
|
||||
GFlashSamplingShowerParameterisation(G4Material* aMat1, G4Material* aMat2,
|
||||
G4double d1, G4double d2,
|
||||
/// \param aMat1 passive material, \param dd1 - passive layer thickness
|
||||
/// \param aMat2 active material, \param dd2 - acive layer thickness
|
||||
|
||||
GFlashSamplingShowerTuning * aPar = 0);
|
||||
GFlashSamplingShowerTuning* aPar = 0);
|
||||
~GFlashSamplingShowerParameterisation();
|
||||
|
||||
void ComputeRadialParameters(G4double y, G4double Tau);
|
||||
void GenerateLongitudinalProfile(G4double Energy);
|
||||
void GenerateLongitudinalProfile(G4double Energy);
|
||||
void ComputeZAX0EFFetc();
|
||||
|
||||
G4double IntegrateEneLongitudinal(G4double LongitudinalStep);
|
||||
G4double IntegrateNspLongitudinal(G4double LongitudinalStep);
|
||||
G4double ComputeTau(G4double LongitudinalPosition);
|
||||
void SetMaterial(G4Material *mat1, G4Material *mat2);
|
||||
void SetMaterial(G4Material* mat1, G4Material* mat2);
|
||||
G4double GeneratePhi();
|
||||
G4double GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition);
|
||||
G4double GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition);
|
||||
G4double GenerateExponential(G4double Energy);
|
||||
|
||||
inline G4double GetAveR99() {return (3.5 * Rmeff);}
|
||||
inline G4double GetAveR90() {return (1.5 * Rmeff);} //ok
|
||||
inline G4double GetAveR99() { return (3.5 * Rmeff); }
|
||||
inline G4double GetAveR90() { return (1.5 * Rmeff); } // ok
|
||||
//
|
||||
inline G4double GetAveTmx() {return (X0eff*std::exp(AveLogTmax));}
|
||||
inline G4double GetAveT99() {return (X0eff*AveLogTmax/(AveLogAlpha-1.00));}
|
||||
inline G4double GetAveT90() {return (2.5* X0eff* std::exp( AveLogTmax));}
|
||||
//
|
||||
inline G4double GetNspot() {return NSpot;}
|
||||
inline G4double GetX0() {return X0eff;}
|
||||
inline G4double GetEc() {return Eceff;}
|
||||
inline G4double GetRm() {return Rmeff;}
|
||||
inline G4double GetAveTmx() { return (X0eff * std::exp(AveLogTmax)); }
|
||||
inline G4double GetAveT99() { return (X0eff * AveLogTmax / (AveLogAlpha - 1.00)); }
|
||||
inline G4double GetAveT90() { return (2.5 * X0eff * std::exp(AveLogTmax)); }
|
||||
//
|
||||
inline G4double GetNspot() { return NSpot; }
|
||||
inline G4double GetX0() { return X0eff; }
|
||||
inline G4double GetEc() { return Eceff; }
|
||||
inline G4double GetRm() { return Rmeff; }
|
||||
inline G4double GetEffDensity() { return Rhoeff; }
|
||||
|
||||
G4double ApplySampling(const G4double DEne, const G4double Energy);
|
||||
|
||||
private:
|
||||
|
||||
// medium related quantities
|
||||
//
|
||||
G4Material *material1, *material2 ;
|
||||
G4double density1, A1, Z1, X01, Ec1, Rm1, d1;
|
||||
G4double density2, A2, Z2, X02, Ec2, Rm2, d2;
|
||||
G4double Aeff, Rhoeff, X0eff, Eceff, Rmeff, Fs, ehat, Zeff;
|
||||
G4Material *material1, *material2;
|
||||
G4double density1, A1, Z1, X01, Ec1, Rm1, d1;
|
||||
G4double density2, A2, Z2, X02, Ec2, Rm2, d2;
|
||||
G4double Aeff, Rhoeff{1.0}, X0eff{1.0}, Eceff{1.0}, Rmeff{1.0}, Fs, ehat, Zeff;
|
||||
|
||||
// Resolution
|
||||
//
|
||||
G4double ConstantResolution;
|
||||
G4double NoiseResolution;
|
||||
G4double ConstantResolution;
|
||||
G4double NoiseResolution;
|
||||
G4double SamplingResolution;
|
||||
|
||||
|
||||
// parametrization parameters
|
||||
//
|
||||
GFlashSamplingShowerTuning * thePar;
|
||||
GFlashSamplingShowerTuning* thePar;
|
||||
|
||||
// Cashed parameters:
|
||||
// Cashed parameters:
|
||||
// Longitudinal Coefficients for a homogenious calo
|
||||
//
|
||||
G4double ParAveT1, ParAveT2;
|
||||
G4double ParAveA1,ParAveA2, ParAveA3;
|
||||
G4double ParSigLogT1,ParSigLogT2;
|
||||
G4double ParSigLogA1,ParSigLogA2;
|
||||
G4double ParRho1,ParRho2;
|
||||
G4double ParAveA1, ParAveA2, ParAveA3;
|
||||
G4double ParSigLogT1, ParSigLogT2;
|
||||
G4double ParSigLogA1, ParSigLogA2;
|
||||
G4double ParRho1, ParRho2;
|
||||
|
||||
//Cashed parameters:
|
||||
// Longitudinal Coefficients for a sampling calo
|
||||
// Cashed parameters:
|
||||
// Longitudinal Coefficients for a sampling calo
|
||||
//
|
||||
G4double ParsAveT1, ParsAveT2;
|
||||
G4double ParsAveA1,ParsAveA2;
|
||||
G4double ParsSigLogT1,ParsSigLogT2;
|
||||
G4double ParsSigLogA1,ParsSigLogA2;
|
||||
G4double ParsRho1,ParsRho2;
|
||||
G4double ParsAveA1, ParsAveA2;
|
||||
G4double ParsSigLogT1, ParsSigLogT2;
|
||||
G4double ParsSigLogA1, ParsSigLogA2;
|
||||
G4double ParsRho1, ParsRho2;
|
||||
void ComputeLongitudinalParameters(G4double y);
|
||||
void GenerateEnergyProfile(G4double y);
|
||||
void GenerateNSpotProfile(G4double y);
|
||||
|
||||
// Radial Coefficients homo
|
||||
//
|
||||
G4double ParRC1,ParRC2,ParRC3,ParRC4;
|
||||
G4double ParWC1,ParWC2,ParWC3;
|
||||
G4double ParWC4,ParWC5,ParWC6;
|
||||
G4double ParRT1,ParRT2,ParRT3,ParRT4;
|
||||
G4double ParRT5,ParRT6;
|
||||
G4double ParRC1, ParRC2, ParRC3, ParRC4;
|
||||
G4double ParWC1, ParWC2, ParWC3;
|
||||
G4double ParWC4, ParWC5, ParWC6;
|
||||
G4double ParRT1, ParRT2, ParRT3, ParRT4;
|
||||
G4double ParRT5, ParRT6;
|
||||
|
||||
// Radial Coefficients sampling
|
||||
//
|
||||
G4double ParsRC1,ParsRC2;
|
||||
G4double ParsWC1,ParsWC2;
|
||||
G4double ParsRT1,ParsRT2;
|
||||
G4double ParsRC1, ParsRC2;
|
||||
G4double ParsWC1, ParsWC2;
|
||||
G4double ParsRT1, ParsRT2;
|
||||
|
||||
// Spot multiplicity Coefficients
|
||||
//
|
||||
G4double ParsSpotT1,ParsSpotT2,ParsSpotA1, ParsSpotA2;
|
||||
G4double ParsSpotN1,ParsSpotN2;
|
||||
G4double ParsSpotT1, ParsSpotT2, ParsSpotA1, ParsSpotA2;
|
||||
G4double ParsSpotN1, ParsSpotN2;
|
||||
|
||||
// PARAMETRISATION variables (Energy & position dependent)
|
||||
// Longitudinal
|
||||
// Longitudinal
|
||||
// homogeneous
|
||||
//
|
||||
G4double AveLogAlphah,AveLogTmaxh;
|
||||
G4double SigmaLogAlphah,SigmaLogTmaxh;
|
||||
G4double AveLogAlphah, AveLogTmaxh;
|
||||
G4double SigmaLogAlphah, SigmaLogTmaxh;
|
||||
G4double Rhoh;
|
||||
G4double Alphah,Tmaxh,Betah;
|
||||
G4double Alphah, Tmaxh, Betah;
|
||||
|
||||
// PARAMETRISATION variables (Energy & position dependent)
|
||||
// Longitudinal
|
||||
// Longitudinal
|
||||
// sampling
|
||||
//
|
||||
G4double AveLogAlpha,AveLogTmax;
|
||||
G4double SigmaLogAlpha,SigmaLogTmax;
|
||||
G4double AveLogAlpha, AveLogTmax;
|
||||
G4double SigmaLogAlpha, SigmaLogTmax;
|
||||
G4double Rho;
|
||||
G4double Alpha,Tmax,Beta;
|
||||
G4double Alpha, Tmax, Beta;
|
||||
|
||||
// Multiplicity
|
||||
//
|
||||
G4double NSpot,AlphaNSpot,TNSpot,BetaNSpot;
|
||||
G4double NSpot, AlphaNSpot, TNSpot, BetaNSpot;
|
||||
|
||||
//Radial
|
||||
// Radial
|
||||
//
|
||||
G4double RadiusCore, WeightCore,RadiusTail;
|
||||
G4double RadiusCore, WeightCore, RadiusTail;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -60,75 +60,72 @@ class GFlashSamplingShowerTuning : public GVFlashHomoShowerTuning
|
||||
|
||||
GFlashSamplingShowerTuning() {}
|
||||
virtual ~GFlashSamplingShowerTuning() {}
|
||||
|
||||
|
||||
public: // with description
|
||||
|
||||
G4double ParsAveT1(){ return -0.55;} // t1
|
||||
G4double ParsAveT2(){ return -0.69;} // t2
|
||||
public: // with description
|
||||
G4double ParsAveT1() { return -0.55; } // t1
|
||||
G4double ParsAveT2() { return -0.69; } // t2
|
||||
// T_sam = log(exp( log T_hom) + t1*Fs-1 + t2*(1-ehat))
|
||||
|
||||
G4double ParsAveA1(){ return -0.476; } // a1
|
||||
G4double ParsAveA1() { return -0.476; } // a1
|
||||
// alpha_sam = log(exp(log alphah_hom) +(a1*Fs-1))
|
||||
|
||||
G4double ParsSigLogT1(){ return -2.5;} // t1
|
||||
G4double ParsSigLogT2(){ return 1.25;} // t2
|
||||
G4double ParsSigLogT1() { return -2.5; } // t1
|
||||
G4double ParsSigLogT2() { return 1.25; } // t2
|
||||
// std::sqrt(var(ln(T_sam))) = 1/(t+t2*ln(y))
|
||||
|
||||
G4double ParsSigLogA1(){ return -0.82;} // a1
|
||||
G4double ParsSigLogA2(){ return 0.79; } // a2
|
||||
G4double ParsSigLogA1() { return -0.82; } // a1
|
||||
G4double ParsSigLogA2() { return 0.79; } // a2
|
||||
// std::sqrt(var(ln(alpha_sam))) = 1/(a1+a2*ln(y))
|
||||
|
||||
G4double ParsRho1(){ return 0.784; } // r1
|
||||
G4double ParsRho2(){ return -0.023;} // r2
|
||||
G4double ParsRho1() { return 0.784; } // r1
|
||||
G4double ParsRho2() { return -0.023; } // r2
|
||||
// Correlation(ln(T),ln(alpha))=r1+r2*ln(y)
|
||||
|
||||
// Radial profiles
|
||||
// f(r) := (1/dE(t))(dE(t,r)/dr)
|
||||
// Ansatz:
|
||||
// f(r) = p(2*r*Rc**2)/(r**2+Rc**2)**2+(1-p)*(2*r*Rt**2)/(r**2+Rt**2)**2,
|
||||
// 0<p<1
|
||||
// Radial profiles
|
||||
// f(r) := (1/dE(t))(dE(t,r)/dr)
|
||||
// Ansatz:
|
||||
// f(r) = p(2*r*Rc**2)/(r**2+Rc**2)**2+(1-p)*(2*r*Rt**2)/(r**2+Rt**2)**2,
|
||||
// 0<p<1
|
||||
|
||||
G4double ParsRC1(){ return -0.0203; } // c1
|
||||
G4double ParsRC2(){ return 0.0397; } // c2
|
||||
G4double ParsRC1() { return -0.0203; } // c1
|
||||
G4double ParsRC2() { return 0.0397; } // c2
|
||||
// Rc_sam = Rc_hom + c1 * (1-ehat) + c2 *Fs-1*exp (-tau)
|
||||
|
||||
G4double ParsRT1(){ return -0.14; } // t1
|
||||
G4double ParsRT2(){ return -0.495; } // t2
|
||||
G4double ParsRT1() { return -0.14; } // t1
|
||||
G4double ParsRT2() { return -0.495; } // t2
|
||||
// Rt_sam = Rc_hom + t1 * (1-ehat) + t2 *Fs-1*exp (-tau)
|
||||
|
||||
G4double ParsWC1(){ return 0.348; } // c1
|
||||
G4double ParsWC2(){ return -0.642;} // c2
|
||||
G4double ParsWC1() { return 0.348; } // c1
|
||||
G4double ParsWC2() { return -0.642; } // c2
|
||||
// W_sam = W_hom + (1-ehat)*(c1 + c2 *Fs-1 * exp (- (tau -1 )**2))
|
||||
|
||||
// Fluctuations on radial profiles through number of spots
|
||||
// The total number of spots needed for a shower is
|
||||
// Fluctuations on radial profiles through number of spots
|
||||
// The total number of spots needed for a shower is
|
||||
|
||||
G4double ParsSpotN1(){ return 10.3; } // n1
|
||||
G4double ParsSpotN2(){ return 0.959;} // n2
|
||||
G4double ParsSpotN1() { return 10.3; } // n1
|
||||
G4double ParsSpotN2() { return 0.959; } // n2
|
||||
// Ns = n1*ln(Z)(E/GeV)**n2
|
||||
|
||||
// The number of spots per longitudinal interval is:
|
||||
// (1/Ns)(dNs(t)/dt) = f(t)
|
||||
// = (beta*t)**(alpha-1)*beta*std::exp(-beta*t)/Gamma(alpha)
|
||||
// <t> = alpha_s/beta_s
|
||||
// Ts = (alpha_s-1)/beta_s
|
||||
// and
|
||||
// Ts = T*(t1+t2*Z)
|
||||
// alpha_s = alpha*(a1+a2*Z)
|
||||
// The number of spots per longitudinal interval is:
|
||||
// (1/Ns)(dNs(t)/dt) = f(t)
|
||||
// = (beta*t)**(alpha-1)*beta*std::exp(-beta*t)/Gamma(alpha)
|
||||
// <t> = alpha_s/beta_s
|
||||
// Ts = (alpha_s-1)/beta_s
|
||||
// and
|
||||
// Ts = T*(t1+t2*Z)
|
||||
// alpha_s = alpha*(a1+a2*Z)
|
||||
|
||||
G4double ParsSpotT1(){ return 0.813; } // t1
|
||||
G4double ParsSpotT2(){ return 0.0019;} // t2
|
||||
G4double ParsSpotT1() { return 0.813; } // t1
|
||||
G4double ParsSpotT2() { return 0.0019; } // t2
|
||||
|
||||
G4double ParsSpotA1(){ return 0.844; } //a1
|
||||
G4double ParsSpotA2(){ return 0.0026;} //a2
|
||||
G4double ParsSpotA1() { return 0.844; } // a1
|
||||
G4double ParsSpotA2() { return 0.0026; } // a2
|
||||
|
||||
// Resolution
|
||||
|
||||
G4double ConstantResolution(){ return 0.00; }
|
||||
G4double NoiseResolution() { return 0.00; } // not used
|
||||
G4double SamplingResolution(){ return 0.11; } // not used
|
||||
// Resolution
|
||||
|
||||
G4double ConstantResolution() { return 0.00; } // not used
|
||||
G4double NoiseResolution() { return 0.00; } // not used
|
||||
G4double SamplingResolution() { return 0.11; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,46 +59,35 @@ class GFlashSamplingShowerParameterisation;
|
||||
class GFlashShowerModel : public G4VFastSimulationModel
|
||||
{
|
||||
public: // with description
|
||||
GFlashShowerModel(G4String, G4Envelope*);
|
||||
GFlashShowerModel(G4String);
|
||||
~GFlashShowerModel();
|
||||
// Constructors, destructor
|
||||
|
||||
GFlashShowerModel (G4String, G4Envelope*);
|
||||
GFlashShowerModel (G4String);
|
||||
~GFlashShowerModel ();
|
||||
// Constructors, destructor
|
||||
|
||||
G4bool ModelTrigger(const G4FastTrack &);
|
||||
G4bool ModelTrigger(const G4FastTrack&);
|
||||
G4bool IsApplicable(const G4ParticleDefinition&);
|
||||
void DoIt(const G4FastTrack&, G4FastStep&);
|
||||
// Checks whether conditions of fast parameterisation are fullfilled
|
||||
|
||||
// Checks whether conditions of fast parameterisation are fullfilled
|
||||
|
||||
// setting
|
||||
|
||||
inline void SetFlagParamType(G4int I)
|
||||
{ FlagParamType = I; }
|
||||
inline void SetFlagParticleContainment(G4int I)
|
||||
{ FlagParticleContainment = I; }
|
||||
inline void SetStepInX0(G4double Lenght)
|
||||
{ StepInX0=Lenght; }
|
||||
inline void SetParameterisation(GVFlashShowerParameterisation &DP)
|
||||
{ Parameterisation=&DP;}
|
||||
inline void SetHitMaker(GFlashHitMaker &Maker)
|
||||
{ HMaker=&Maker; }
|
||||
inline void SetParticleBounds(GFlashParticleBounds &SpecificBound)
|
||||
{ PBound =&SpecificBound; }
|
||||
|
||||
inline void SetFlagParamType(G4int I) { FlagParamType = I; }
|
||||
inline void SetFlagParticleContainment(G4int I) { FlagParticleContainment = I; }
|
||||
inline void SetStepInX0(G4double Lenght) { StepInX0 = Lenght; }
|
||||
inline void SetParameterisation(GVFlashShowerParameterisation& DP) { Parameterisation = &DP; }
|
||||
inline void SetHitMaker(GFlashHitMaker& Maker) { HMaker = &Maker; }
|
||||
inline void SetParticleBounds(GFlashParticleBounds& SpecificBound) { PBound = &SpecificBound; }
|
||||
|
||||
// getting
|
||||
|
||||
inline G4int GetFlagParamType()
|
||||
{ return FlagParamType; }
|
||||
inline G4int GetFlagParticleContainment()
|
||||
{ return FlagParticleContainment; }
|
||||
inline G4double GetStepInX0()
|
||||
{ return StepInX0; }
|
||||
inline G4int GetFlagParamType() { return FlagParamType; }
|
||||
inline G4int GetFlagParticleContainment() { return FlagParticleContainment; }
|
||||
inline G4double GetStepInX0() { return StepInX0; }
|
||||
|
||||
public: // without description
|
||||
|
||||
// Gets ?
|
||||
// Gets ?
|
||||
GFlashParticleBounds *PBound;
|
||||
GVFlashShowerParameterisation *Parameterisation;
|
||||
GVFlashShowerParameterisation* Parameterisation;
|
||||
|
||||
private:
|
||||
|
||||
@@ -107,17 +96,15 @@ class GFlashShowerModel : public G4VFastSimulationModel
|
||||
// void NeutrinoDoIt(const G4FastTrack&, G4FastStep&);
|
||||
G4bool CheckParticleDefAndContainment(const G4FastTrack &fastTrack);
|
||||
G4bool CheckContainment(const G4FastTrack &fastTrack);
|
||||
|
||||
private:
|
||||
|
||||
GFlashHitMaker *HMaker;
|
||||
private:
|
||||
GFlashHitMaker* HMaker;
|
||||
GFlashShowerModelMessenger* Messenger;
|
||||
|
||||
|
||||
//Control Flags
|
||||
G4int FlagParamType; ///0=no GFlash 1=only em showers parametrized
|
||||
G4int FlagParticleContainment; ///0=no check ///1=only fully contained...
|
||||
G4double StepInX0;
|
||||
G4double StepInX0;
|
||||
G4double EnergyStop;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -52,26 +52,24 @@ class G4UIcmdWithAnInteger;
|
||||
class G4UIcmdWithADoubleAndUnit;
|
||||
class G4UIcmdWithADouble;
|
||||
|
||||
class GFlashShowerModelMessenger: public G4UImessenger
|
||||
class GFlashShowerModelMessenger : public G4UImessenger
|
||||
{
|
||||
public:
|
||||
|
||||
GFlashShowerModelMessenger(GFlashShowerModel * myModel);
|
||||
GFlashShowerModelMessenger(GFlashShowerModel* myModel);
|
||||
~GFlashShowerModelMessenger();
|
||||
|
||||
void SetNewValue(G4UIcommand * command,G4String newValues);
|
||||
G4String GetCurrentValue(G4UIcommand * command);
|
||||
|
||||
private:
|
||||
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues);
|
||||
G4String GetCurrentValue(G4UIcommand* command);
|
||||
|
||||
private:
|
||||
GFlashShowerModel* myModel;
|
||||
G4UIdirectory* myParaDir;
|
||||
G4UIcmdWithAnInteger* FlagCmd;
|
||||
G4UIcmdWithAnInteger* ContCmd; // Containment Check
|
||||
G4UIcmdWithADouble* StepInX0Cmd;
|
||||
G4UIcmdWithADoubleAndUnit* EmaxCmd;
|
||||
G4UIcmdWithADoubleAndUnit* EminCmd;
|
||||
G4UIcmdWithADoubleAndUnit* EkillCmd;
|
||||
G4UIdirectory* myParaDir;
|
||||
G4UIcmdWithAnInteger* FlagCmd;
|
||||
G4UIcmdWithAnInteger* ContCmd; // Containment Check
|
||||
G4UIcmdWithADouble* StepInX0Cmd;
|
||||
G4UIcmdWithADoubleAndUnit* EmaxCmd;
|
||||
G4UIcmdWithADoubleAndUnit* EminCmd;
|
||||
G4UIcmdWithADoubleAndUnit* EkillCmd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,22 +70,21 @@ class GVFlashHomoShowerTuning
|
||||
public:
|
||||
GVFlashHomoShowerTuning() {}
|
||||
virtual ~GVFlashHomoShowerTuning() {}
|
||||
|
||||
public: // with description
|
||||
|
||||
virtual G4double ParAveT1(){ return -0.812; } // t1
|
||||
virtual G4double ParAveA1(){ return 0.81; } // a1
|
||||
public: // with description
|
||||
virtual G4double ParAveT1() { return -0.812; } // t1
|
||||
virtual G4double ParAveA1() { return 0.81; } // a1
|
||||
virtual G4double ParAveA2(){ return 0.458; } // a2
|
||||
virtual G4double ParAveA3(){ return 2.26; } // a3
|
||||
|
||||
virtual G4double ParSigLogT1(){ return -1.4; } // t1
|
||||
virtual G4double ParSigLogT2(){ return 1.26;} // t2
|
||||
// std::sqrt(var(ln(T))) = 1/(t+t2*ln(y))
|
||||
virtual G4double ParAveA3() { return 2.26; } // a3
|
||||
|
||||
virtual G4double ParSigLogT1() { return -1.4; } // t1
|
||||
virtual G4double ParSigLogT2() { return 1.26; } // t2
|
||||
// std::sqrt(var(ln(T))) = 1/(t+t2*ln(y))
|
||||
|
||||
virtual G4double ParSigLogA1(){ return -0.58; } // a1
|
||||
virtual G4double ParSigLogA2(){ return 0.86; } // a2
|
||||
// std::sqrt(var(ln(alpha))) = 1/(a1+a2*ln(y))
|
||||
|
||||
|
||||
virtual G4double ParRho1(){ return 0.705; } // r1
|
||||
virtual G4double ParRho2(){ return -0.023; } // r2
|
||||
// Correlation(ln(T),ln(alpha))=r1+r2*ln(y)
|
||||
@@ -103,7 +102,7 @@ class GVFlashHomoShowerTuning
|
||||
// Rc (t/T)= z1 +z2*t/T
|
||||
// z1 = c1+c2*ln(E/GeV)
|
||||
// z2 = c3+c4*Z
|
||||
|
||||
|
||||
virtual G4double ParRT1(){ return 0.659; } // t1
|
||||
virtual G4double ParRT2(){ return -0.00309;} // t2
|
||||
virtual G4double ParRT3(){ return 0.645; } // k2
|
||||
@@ -113,7 +112,7 @@ class GVFlashHomoShowerTuning
|
||||
// Rt (t/T)= k1*(std::exp(k3*(t/T-k2))+std::exp(k4*(t/T-k2)))
|
||||
// k1 = t1+t2*Z
|
||||
// k4 = t5+t6*ln(E/GeV)
|
||||
|
||||
|
||||
virtual G4double ParWC1(){ return 2.632; } // c1
|
||||
virtual G4double ParWC2(){ return -0.00094;} // c2
|
||||
virtual G4double ParWC3(){ return 0.401; } // c3
|
||||
@@ -141,11 +140,10 @@ class GVFlashHomoShowerTuning
|
||||
// alpha_s = alpha*(a1+a2*Z)
|
||||
|
||||
virtual G4double ParSpotT1(){ return 0.698; } // t1
|
||||
virtual G4double ParSpotT2(){ return 0.00212;} // t2
|
||||
|
||||
virtual G4double ParSpotA1(){ return 0.639; } //a1
|
||||
virtual G4double ParSpotA2(){ return 0.00334;} //a2
|
||||
virtual G4double ParSpotT2() { return 0.00212; } // t2
|
||||
|
||||
virtual G4double ParSpotA1() { return 0.639; } // a1
|
||||
virtual G4double ParSpotA2() { return 0.00334; } // a2
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,55 +46,51 @@
|
||||
class MyGamma;
|
||||
class G4Material;
|
||||
|
||||
|
||||
class GVFlashShowerParameterisation
|
||||
{
|
||||
public: // with description
|
||||
|
||||
GVFlashShowerParameterisation();
|
||||
virtual ~GVFlashShowerParameterisation();
|
||||
|
||||
virtual void ComputeRadialParameters(G4double y, G4double Tau) = 0;
|
||||
virtual void GenerateLongitudinalProfile(G4double Energy) = 0;
|
||||
virtual G4double IntegrateEneLongitudinal(G4double LongitudinalStep) = 0;
|
||||
virtual G4double IntegrateNspLongitudinal(G4double LongitudinalStep) = 0;
|
||||
virtual G4double ComputeTau(G4double LongitudinalPosition) = 0;
|
||||
virtual G4double GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition) = 0;
|
||||
virtual void ComputeLongitudinalParameters(G4double y) = 0;
|
||||
virtual void GenerateEnergyProfile(G4double y) = 0;
|
||||
virtual void GenerateNSpotProfile(G4double y) = 0;
|
||||
virtual G4double GenerateExponential(G4double Energy) = 0;
|
||||
|
||||
virtual G4double GetAveR99() = 0;
|
||||
virtual G4double GetAveR90() = 0;
|
||||
|
||||
virtual G4double GetAveTmx() = 0;
|
||||
virtual G4double GetAveT99() = 0;
|
||||
virtual G4double GetAveT90() = 0;
|
||||
|
||||
virtual G4double GetNspot() = 0;
|
||||
virtual G4double GetX0() = 0;
|
||||
virtual G4double GetEc() = 0;
|
||||
virtual G4double GetRm() = 0;
|
||||
|
||||
G4double GeneratePhi();
|
||||
G4double GetEffZ(const G4Material * material);
|
||||
G4double GetEffA(const G4Material * material);
|
||||
G4double gam(G4double x, G4double a) const; // @@@@ gamma function
|
||||
void PrintMaterial(const G4Material * mat);
|
||||
|
||||
protected:
|
||||
|
||||
GVFlashHomoShowerTuning * thePar;
|
||||
// Parameterisation parameters
|
||||
G4double density, A, Z, X0, Ec, Rm;
|
||||
// Medium related quantities
|
||||
G4double NSpot;
|
||||
|
||||
private:
|
||||
MyGamma* fGamma;
|
||||
|
||||
public: // with description
|
||||
GVFlashShowerParameterisation();
|
||||
virtual ~GVFlashShowerParameterisation();
|
||||
|
||||
virtual void ComputeRadialParameters(G4double y, G4double Tau) = 0;
|
||||
virtual void GenerateLongitudinalProfile(G4double Energy) = 0;
|
||||
virtual G4double IntegrateEneLongitudinal(G4double LongitudinalStep) = 0;
|
||||
virtual G4double IntegrateNspLongitudinal(G4double LongitudinalStep) = 0;
|
||||
virtual G4double ComputeTau(G4double LongitudinalPosition) = 0;
|
||||
virtual G4double GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition) = 0;
|
||||
virtual void ComputeLongitudinalParameters(G4double y) = 0;
|
||||
virtual void GenerateEnergyProfile(G4double y) = 0;
|
||||
virtual void GenerateNSpotProfile(G4double y) = 0;
|
||||
virtual G4double GenerateExponential(G4double Energy) = 0;
|
||||
|
||||
virtual G4double GetAveR99() = 0;
|
||||
virtual G4double GetAveR90() = 0;
|
||||
|
||||
virtual G4double GetAveTmx() = 0;
|
||||
virtual G4double GetAveT99() = 0;
|
||||
virtual G4double GetAveT90() = 0;
|
||||
|
||||
virtual G4double GetNspot() = 0;
|
||||
virtual G4double GetX0() = 0;
|
||||
virtual G4double GetEc() = 0;
|
||||
virtual G4double GetRm() = 0;
|
||||
|
||||
G4double GeneratePhi();
|
||||
G4double GetEffZ(const G4Material* material);
|
||||
G4double GetEffA(const G4Material* material);
|
||||
G4double gam(G4double x, G4double a) const; // @@@@ gamma function
|
||||
void PrintMaterial(const G4Material* mat);
|
||||
|
||||
protected:
|
||||
GVFlashHomoShowerTuning* thePar;
|
||||
// Parameterisation parameters
|
||||
G4double density, A, Z, X0, Ec, Rm;
|
||||
// Medium related quantities
|
||||
G4double NSpot;
|
||||
|
||||
private:
|
||||
MyGamma* fGamma;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,25 +45,23 @@
|
||||
class MyGamma
|
||||
{
|
||||
public:
|
||||
|
||||
MyGamma ();
|
||||
MyGamma();
|
||||
~MyGamma();
|
||||
|
||||
|
||||
double Gamma(double z);
|
||||
double Gamma(double a,double x);
|
||||
double Gamma(double a, double x);
|
||||
|
||||
private:
|
||||
double GamCf(double a, double x);
|
||||
double GamSer(double a, double x);
|
||||
|
||||
double GamCf(double a,double x);
|
||||
double GamSer(double a,double x);
|
||||
|
||||
// Abs
|
||||
static short Abs(short d) { return (d > 0) ? d : -d; }
|
||||
static int Abs(int d) { return (d > 0) ? d : -d; }
|
||||
static short Abs(short d) { return (d > 0) ? d : -d; }
|
||||
static int Abs(int d) { return (d > 0) ? d : -d; }
|
||||
static long Abs(long d) { return (d > 0) ? d : -d; }
|
||||
static float Abs(float d) { return (d > 0) ? d : -d; }
|
||||
static double Abs(double d) { return (d > 0) ? d : -d; }
|
||||
static double LnGamma(double z);
|
||||
static double LnGamma(double z);
|
||||
static double Log(double x) { return std::log(x); }
|
||||
static double Exp(double x) { return std::exp(x); }
|
||||
};
|
||||
|
||||
@@ -30,26 +30,26 @@
|
||||
//
|
||||
// ---------------- GFlashHitMaker ----------------
|
||||
//
|
||||
// Authors: E.Barberio & Joanna Weng
|
||||
// Authors: E.Barberio & Joanna Weng
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4VSensitiveDetector.hh"
|
||||
#include "G4TouchableHandle.hh"
|
||||
#include "G4VGFlashSensitiveDetector.hh"
|
||||
|
||||
#include "GFlashHitMaker.hh"
|
||||
|
||||
#include "G4GFlashSpot.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
#include "G4TouchableHandle.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4VGFlashSensitiveDetector.hh"
|
||||
#include "G4VSensitiveDetector.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
GFlashHitMaker::GFlashHitMaker()
|
||||
{
|
||||
fTouchableHandle = new G4TouchableHistory(); // talk to ?@@@
|
||||
fpNavigator = new G4Navigator();
|
||||
fNaviSetup = false;
|
||||
fWorldWithSdName = "";
|
||||
fTouchableHandle = new G4TouchableHistory(); // talk to ?@@@
|
||||
fpNavigator = new G4Navigator();
|
||||
fNaviSetup = false;
|
||||
fWorldWithSdName = "";
|
||||
fpSpotS = new G4Step();
|
||||
fpSpotP = new G4StepPoint();
|
||||
// N.B. Pre and Post step points are common.
|
||||
@@ -66,52 +66,49 @@ GFlashHitMaker::~GFlashHitMaker()
|
||||
delete fpSpotS;
|
||||
}
|
||||
|
||||
void GFlashHitMaker::make(GFlashEnergySpot * aSpot, const G4FastTrack * aT)
|
||||
void GFlashHitMaker::make(GFlashEnergySpot* aSpot, const G4FastTrack* aT)
|
||||
{
|
||||
// Locate the spot
|
||||
if (!fNaviSetup)
|
||||
{
|
||||
// Choose the world volume that contains the sensitive detector based on its name (empty name for mass geometry)
|
||||
if (!fNaviSetup) {
|
||||
// Choose the world volume that contains the sensitive detector based on its name (empty name
|
||||
// for mass geometry)
|
||||
G4VPhysicalVolume* worldWithSD = nullptr;
|
||||
if(fWorldWithSdName.empty()) {
|
||||
worldWithSD = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
|
||||
} else {
|
||||
worldWithSD = G4TransportationManager::GetTransportationManager()->GetParallelWorld(fWorldWithSdName);
|
||||
if (fWorldWithSdName.empty()) {
|
||||
worldWithSD = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking()
|
||||
->GetWorldVolume();
|
||||
}
|
||||
else {
|
||||
worldWithSD =
|
||||
G4TransportationManager::GetTransportationManager()->GetParallelWorld(fWorldWithSdName);
|
||||
}
|
||||
fpNavigator->SetWorldVolume(worldWithSD);
|
||||
fpNavigator->
|
||||
LocateGlobalPointAndUpdateTouchable(aSpot->GetPosition(),
|
||||
fTouchableHandle(), false);
|
||||
fpNavigator->LocateGlobalPointAndUpdateTouchable(aSpot->GetPosition(), fTouchableHandle(),
|
||||
false);
|
||||
fNaviSetup = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fpNavigator->
|
||||
LocateGlobalPointAndUpdateTouchable(aSpot->GetPosition(),
|
||||
fTouchableHandle());
|
||||
else {
|
||||
fpNavigator->LocateGlobalPointAndUpdateTouchable(aSpot->GetPosition(), fTouchableHandle());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
// Produce Hits
|
||||
// call sensitive part: taken/adapted from the stepping:
|
||||
// Send G4Step information to Hit/Dig if the volume is sensitive
|
||||
//--------------G4TouchableHistory----------------------------------------
|
||||
|
||||
G4VPhysicalVolume* pCurrentVolume = fTouchableHandle()->GetVolume();
|
||||
|
||||
G4VPhysicalVolume* pCurrentVolume = fTouchableHandle()->GetVolume();
|
||||
G4VSensitiveDetector* pSensitive;
|
||||
if( pCurrentVolume != 0 )
|
||||
{
|
||||
if (pCurrentVolume != 0) {
|
||||
pSensitive = pCurrentVolume->GetLogicalVolume()->GetSensitiveDetector();
|
||||
G4VGFlashSensitiveDetector * gflashSensitive =
|
||||
dynamic_cast<G4VGFlashSensitiveDetector * > (pSensitive);
|
||||
if( gflashSensitive )
|
||||
{
|
||||
G4VGFlashSensitiveDetector* gflashSensitive =
|
||||
dynamic_cast<G4VGFlashSensitiveDetector*>(pSensitive);
|
||||
if (gflashSensitive) {
|
||||
// set spot information:
|
||||
G4GFlashSpot theSpot(aSpot, aT, fTouchableHandle);
|
||||
gflashSensitive->Hit(&theSpot);
|
||||
}
|
||||
else if( pSensitive )
|
||||
{
|
||||
else if (pSensitive) {
|
||||
fpSpotS->SetTotalEnergyDeposit(aSpot->GetEnergy());
|
||||
fpSpotS->SetTrack(const_cast<G4Track*>(aT->GetPrimaryTrack()));
|
||||
fpSpotP->SetWeight(aT->GetPrimaryTrack()->GetWeight());
|
||||
@@ -125,10 +122,9 @@ void GFlashHitMaker::make(GFlashEnergySpot * aSpot, const G4FastTrack * aT)
|
||||
pSensitive->Hit(fpSpotS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GFLASH_DEBUG
|
||||
G4cout << "GFlashHitMaker::Out of volume "<< G4endl;
|
||||
#endif
|
||||
else {
|
||||
#ifdef GFLASH_DEBUG
|
||||
G4cout << "GFlashHitMaker::Out of volume " << G4endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,18 +44,26 @@
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
|
||||
GFlashHomoShowerParameterisation::
|
||||
GFlashHomoShowerParameterisation(G4Material * aMat,
|
||||
GVFlashHomoShowerTuning * aPar)
|
||||
GFlashHomoShowerParameterisation::GFlashHomoShowerParameterisation(G4Material* aMat,
|
||||
GVFlashHomoShowerTuning* aPar)
|
||||
: GVFlashShowerParameterisation(),
|
||||
ConstantResolution(0.), NoiseResolution(0.), SamplingResolution(0.),
|
||||
AveLogAlphah(0.), AveLogTmaxh(0.), SigmaLogAlphah(0.), SigmaLogTmaxh(0.),
|
||||
Rhoh(0.), Alphah(0.), Tmaxh(0.), Betah(0.)
|
||||
ConstantResolution(0.),
|
||||
NoiseResolution(0.),
|
||||
SamplingResolution(0.),
|
||||
AveLogAlphah(0.),
|
||||
AveLogTmaxh(0.),
|
||||
SigmaLogAlphah(0.),
|
||||
SigmaLogTmaxh(0.),
|
||||
Rhoh(0.),
|
||||
Alphah(0.),
|
||||
Tmaxh(0.),
|
||||
Betah(0.)
|
||||
|
||||
{
|
||||
if(!aPar) {
|
||||
{
|
||||
if (!aPar) {
|
||||
thePar = new GVFlashHomoShowerTuning;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thePar = aPar;
|
||||
}
|
||||
|
||||
@@ -64,91 +72,94 @@ GFlashHomoShowerParameterisation(G4Material * aMat,
|
||||
|
||||
/********************************************/
|
||||
/* Homo Calorimeter */
|
||||
/********************************************/
|
||||
/********************************************/
|
||||
// Longitudinal Coefficients for a homogenious calo
|
||||
// shower max
|
||||
//
|
||||
ParAveT1 = thePar->ParAveT1(); // ln (ln y -0.812)
|
||||
ParAveA1 = thePar->ParAveA1(); // ln a (0.81 + (0.458 + 2.26/Z)ln y)
|
||||
ParAveA2 = thePar->ParAveA2();
|
||||
ParAveA3 = thePar->ParAveA3();
|
||||
ParAveT1 = thePar->ParAveT1(); // ln (ln y -0.812)
|
||||
ParAveA1 = thePar->ParAveA1(); // ln a (0.81 + (0.458 + 2.26/Z)ln y)
|
||||
ParAveA2 = thePar->ParAveA2();
|
||||
ParAveA3 = thePar->ParAveA3();
|
||||
|
||||
// Variance of shower max
|
||||
ParSigLogT1 = thePar->ParSigLogT1(); // Sigma T1 (-1.4 + 1.26 ln y)**-1
|
||||
ParSigLogT1 = thePar->ParSigLogT1(); // Sigma T1 (-1.4 + 1.26 ln y)**-1
|
||||
ParSigLogT2 = thePar->ParSigLogT2();
|
||||
|
||||
// variance of 'alpha'
|
||||
//
|
||||
ParSigLogA1 = thePar->ParSigLogA1(); // Sigma a (-0.58 + 0.86 ln y)**-1
|
||||
ParSigLogA1 = thePar->ParSigLogA1(); // Sigma a (-0.58 + 0.86 ln y)**-1
|
||||
ParSigLogA2 = thePar->ParSigLogA2();
|
||||
|
||||
// correlation alpha%T
|
||||
//
|
||||
ParRho1 = thePar->ParRho1(); // Rho = 0.705 -0.023 ln y
|
||||
ParRho2 = thePar->ParRho2();
|
||||
ParRho1 = thePar->ParRho1(); // Rho = 0.705 -0.023 ln y
|
||||
ParRho2 = thePar->ParRho2();
|
||||
|
||||
// Radial Coefficients
|
||||
// r_C (tau)= z_1 +z_2 tau
|
||||
// r_t (tau)= k1 (std::exp (k3(tau -k2 ))+std::exp (k_4 (tau- k_2))))
|
||||
//
|
||||
ParRC1 = thePar->ParRC1(); // z_1 = 0.0251 + 0.00319 ln E
|
||||
ParRC2 = thePar->ParRC2();
|
||||
ParRC1 = thePar->ParRC1(); // z_1 = 0.0251 + 0.00319 ln E
|
||||
ParRC2 = thePar->ParRC2();
|
||||
|
||||
ParRC3 = thePar->ParRC3(); // z_2 = 0.1162 + - 0.000381 Z
|
||||
ParRC4 = thePar->ParRC4();
|
||||
ParRC3 = thePar->ParRC3(); // z_2 = 0.1162 + - 0.000381 Z
|
||||
ParRC4 = thePar->ParRC4();
|
||||
|
||||
ParWC1 = thePar->ParWC1();
|
||||
ParWC2 = thePar->ParWC2();
|
||||
ParWC3 = thePar->ParWC3();
|
||||
ParWC4 = thePar->ParWC4();
|
||||
ParWC5 = thePar->ParWC5();
|
||||
ParWC5 = thePar->ParWC5();
|
||||
ParWC6 = thePar->ParWC6();
|
||||
|
||||
ParRT1 = thePar->ParRT1();
|
||||
ParRT2 = thePar->ParRT2();
|
||||
ParRT3 = thePar->ParRT3();
|
||||
ParRT4 = thePar->ParRT4();
|
||||
ParRT4 = thePar->ParRT4();
|
||||
ParRT5 = thePar->ParRT5();
|
||||
ParRT6 = thePar->ParRT6();
|
||||
|
||||
// Coeff for fluctueted radial profiles for a uniform media
|
||||
//
|
||||
ParSpotT1 = thePar->ParSpotT1(); // T_spot = T_hom =(0.698 + 0.00212)
|
||||
ParSpotT2 = thePar->ParSpotT2();
|
||||
ParSpotT1 = thePar->ParSpotT1(); // T_spot = T_hom =(0.698 + 0.00212)
|
||||
ParSpotT2 = thePar->ParSpotT2();
|
||||
|
||||
ParSpotA1 = thePar->ParSpotA1(); // a_spot= a_hom (0.639 + 0.00334)
|
||||
ParSpotA2 = thePar->ParSpotA2();
|
||||
ParSpotA1 = thePar->ParSpotA1(); // a_spot= a_hom (0.639 + 0.00334)
|
||||
ParSpotA2 = thePar->ParSpotA2();
|
||||
|
||||
ParSpotN1 = thePar->ParSpotN1(); // N_Spot 93 * ln(Z) E ** 0.876
|
||||
ParSpotN2 = thePar->ParSpotN2();
|
||||
ParSpotN1 = thePar->ParSpotN1(); // N_Spot 93 * ln(Z) E ** 0.876
|
||||
ParSpotN2 = thePar->ParSpotN2();
|
||||
|
||||
// Inits
|
||||
|
||||
NSpot = 0.00;
|
||||
AlphaNSpot = 0.00;
|
||||
TNSpot = 0.00;
|
||||
BetaNSpot = 0.00;
|
||||
NSpot = 0.00;
|
||||
AlphaNSpot = 0.00;
|
||||
TNSpot = 0.00;
|
||||
BetaNSpot = 0.00;
|
||||
|
||||
RadiusCore = 0.00;
|
||||
WeightCore = 0.00;
|
||||
RadiusTail = 0.00;
|
||||
RadiusCore = 0.00;
|
||||
WeightCore = 0.00;
|
||||
RadiusTail = 0.00;
|
||||
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
G4cout << " - GFlashHomoShowerParameterisation::Constructor - " << G4endl;
|
||||
G4cout << " - GFlashHomoShowerParameterisation::Constructor - " << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
}
|
||||
|
||||
void GFlashHomoShowerParameterisation::SetMaterial(G4Material *mat)
|
||||
void GFlashHomoShowerParameterisation::SetMaterial(G4Material* mat)
|
||||
{
|
||||
material= mat;
|
||||
material = mat;
|
||||
Z = GetEffZ(material);
|
||||
A = GetEffA(material);
|
||||
density = material->GetDensity()/(g/cm3);
|
||||
X0 = material->GetRadlen();
|
||||
Ec = 2.66 * std::pow((X0 * Z / A),1.1);
|
||||
G4double Es = 21*MeV;
|
||||
Rm = X0*Es/Ec;
|
||||
// PrintMaterial();
|
||||
density = material->GetDensity() / (g / cm3);
|
||||
X0 = material->GetRadlen();
|
||||
// O. I. Dovzhenkko and A. A. Pommanskii
|
||||
Ec = 2.66 * std::pow((X0 * Z / A), 1.1);
|
||||
// // Rossi appriximation
|
||||
// Ec = 610.0 * MeV / (Z + 1.24);
|
||||
const G4double Es = 21.2 * MeV;
|
||||
Rm = X0 * Es / Ec;
|
||||
// PrintMaterial();
|
||||
}
|
||||
|
||||
GFlashHomoShowerParameterisation::~GFlashHomoShowerParameterisation()
|
||||
@@ -156,59 +167,56 @@ GFlashHomoShowerParameterisation::~GFlashHomoShowerParameterisation()
|
||||
delete thePar;
|
||||
}
|
||||
|
||||
void GFlashHomoShowerParameterisation::
|
||||
GenerateLongitudinalProfile(G4double Energy)
|
||||
void GFlashHomoShowerParameterisation::GenerateLongitudinalProfile(G4double Energy)
|
||||
{
|
||||
if (material==0)
|
||||
{
|
||||
G4Exception("GFlashHomoShowerParameterisation::GenerateLongitudinalProfile()",
|
||||
"InvalidSetup", FatalException, "No material initialized!");
|
||||
if (material == 0) {
|
||||
G4Exception("GFlashHomoShowerParameterisation::GenerateLongitudinalProfile()", "InvalidSetup",
|
||||
FatalException, "No material initialized!");
|
||||
}
|
||||
|
||||
G4double y = Energy/Ec;
|
||||
ComputeLongitudinalParameters(y);
|
||||
|
||||
G4double y = Energy / Ec;
|
||||
ComputeLongitudinalParameters(y);
|
||||
GenerateEnergyProfile(y);
|
||||
GenerateNSpotProfile(y);
|
||||
}
|
||||
|
||||
void
|
||||
GFlashHomoShowerParameterisation::ComputeLongitudinalParameters(G4double y)
|
||||
void GFlashHomoShowerParameterisation::ComputeLongitudinalParameters(G4double y)
|
||||
{
|
||||
AveLogTmaxh = std::log(ParAveT1 + std::log(y));
|
||||
//ok <ln T hom>
|
||||
AveLogAlphah = std::log(ParAveA1 + (ParAveA2+ParAveA3/Z)*std::log(y));
|
||||
//ok <ln alpha hom>
|
||||
AveLogTmaxh = std::log(ParAveT1 + std::log(y));
|
||||
// ok <ln T hom>
|
||||
AveLogAlphah = std::log(ParAveA1 + (ParAveA2 + ParAveA3 / Z) * std::log(y));
|
||||
// ok <ln alpha hom>
|
||||
|
||||
SigmaLogTmaxh = 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y)) ;
|
||||
//ok sigma (ln T hom)
|
||||
SigmaLogAlphah = 1.00/( ParSigLogA1 + ParSigLogA2*std::log(y));
|
||||
//ok sigma (ln alpha hom)
|
||||
Rhoh = ParRho1+ParRho2*std::log(y); //ok
|
||||
SigmaLogTmaxh = 1.00 / (ParSigLogT1 + ParSigLogT2 * std::log(y));
|
||||
// ok sigma (ln T hom)
|
||||
SigmaLogAlphah = 1.00 / (ParSigLogA1 + ParSigLogA2 * std::log(y));
|
||||
// ok sigma (ln alpha hom)
|
||||
Rhoh = ParRho1 + ParRho2 * std::log(y); // ok
|
||||
}
|
||||
|
||||
void GFlashHomoShowerParameterisation::GenerateEnergyProfile(G4double /* y */)
|
||||
{
|
||||
G4double Correlation1h = std::sqrt((1+Rhoh)/2);
|
||||
G4double Correlation2h = std::sqrt((1-Rhoh)/2);
|
||||
{
|
||||
G4double Correlation1h = std::sqrt((1 + Rhoh) / 2);
|
||||
G4double Correlation2h = std::sqrt((1 - Rhoh) / 2);
|
||||
|
||||
G4double Random1 = G4RandGauss::shoot();
|
||||
G4double Random2 = G4RandGauss::shoot();
|
||||
|
||||
// Parameters for Enenrgy Profile including correaltion and sigmas
|
||||
|
||||
Tmaxh = std::exp( AveLogTmaxh + SigmaLogTmaxh *
|
||||
(Correlation1h*Random1 + Correlation2h*Random2) );
|
||||
Alphah = std::exp( AveLogAlphah + SigmaLogAlphah *
|
||||
(Correlation1h*Random1 - Correlation2h*Random2) );
|
||||
Betah = (Alphah-1.00)/Tmaxh;
|
||||
// Parameters for Enenrgy Profile including correaltion and sigmas
|
||||
|
||||
Tmaxh =
|
||||
std::exp(AveLogTmaxh + SigmaLogTmaxh * (Correlation1h * Random1 + Correlation2h * Random2));
|
||||
Alphah =
|
||||
std::exp(AveLogAlphah + SigmaLogAlphah * (Correlation1h * Random1 - Correlation2h * Random2));
|
||||
Betah = (Alphah - 1.00) / Tmaxh;
|
||||
}
|
||||
|
||||
void GFlashHomoShowerParameterisation::GenerateNSpotProfile(const G4double y)
|
||||
{
|
||||
TNSpot = Tmaxh * (ParSpotT1+ParSpotT2*Z); // ok
|
||||
AlphaNSpot = Alphah * (ParSpotA1+ParSpotA2*Z);
|
||||
BetaNSpot = (AlphaNSpot-1.00)/TNSpot; // ok
|
||||
NSpot = ParSpotN1 * std::log(Z)*std::pow((y*Ec)/GeV,ParSpotN2 ); // ok
|
||||
TNSpot = Tmaxh * (ParSpotT1 + ParSpotT2 * Z); // ok
|
||||
AlphaNSpot = Alphah * (ParSpotA1 + ParSpotA2 * Z);
|
||||
BetaNSpot = (AlphaNSpot - 1.00) / TNSpot; // ok
|
||||
NSpot = ParSpotN1 * std::log(Z) * std::pow((y * Ec) / GeV, ParSpotN2); // ok
|
||||
}
|
||||
|
||||
G4double GFlashHomoShowerParameterisation::
|
||||
@@ -222,75 +230,68 @@ IntegrateEneLongitudinal(G4double LongitudinalStep)
|
||||
return DEne;
|
||||
}
|
||||
|
||||
G4double GFlashHomoShowerParameterisation::
|
||||
IntegrateNspLongitudinal(G4double LongitudinalStep)
|
||||
G4double GFlashHomoShowerParameterisation::IntegrateNspLongitudinal(G4double LongitudinalStep)
|
||||
{
|
||||
G4double LongitudinalStepInX0 = LongitudinalStep / X0;
|
||||
G4float x1 = BetaNSpot*LongitudinalStepInX0;
|
||||
G4double LongitudinalStepInX0 = LongitudinalStep / X0;
|
||||
G4float x1 = BetaNSpot * LongitudinalStepInX0;
|
||||
G4float x2 = AlphaNSpot;
|
||||
G4float x3 = gam(x1,x2);
|
||||
G4float x3 = gam(x1, x2);
|
||||
G4double DNsp = x3;
|
||||
return DNsp;
|
||||
}
|
||||
|
||||
|
||||
G4double GFlashHomoShowerParameterisation::
|
||||
GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition)
|
||||
G4double GFlashHomoShowerParameterisation::GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition)
|
||||
{
|
||||
if(ispot < 1)
|
||||
{
|
||||
if (ispot < 1) {
|
||||
// Determine lateral parameters in the middle of the step.
|
||||
// They depend on energy & position along step.
|
||||
//
|
||||
G4double Tau = ComputeTau(LongitudinalPosition);
|
||||
ComputeRadialParameters(Energy,Tau);
|
||||
ComputeRadialParameters(Energy, Tau);
|
||||
}
|
||||
|
||||
G4double Radius;
|
||||
G4double Random1 = G4UniformRand();
|
||||
G4double Random2 = G4UniformRand();
|
||||
G4double Random2 = G4UniformRand();
|
||||
|
||||
if(Random1 <WeightCore) //WeightCore = p < w_i
|
||||
if (Random1 < WeightCore) // WeightCore = p < w_i
|
||||
{
|
||||
Radius = Rm * RadiusCore * std::sqrt( Random2/(1. - Random2) );
|
||||
Radius = Rm * RadiusCore * std::sqrt(Random2 / (1. - Random2));
|
||||
}
|
||||
else
|
||||
{
|
||||
Radius = Rm * RadiusTail * std::sqrt( Random2/(1. - Random2) );
|
||||
}
|
||||
Radius = std::min(Radius,DBL_MAX);
|
||||
else {
|
||||
Radius = Rm * RadiusTail * std::sqrt(Random2 / (1. - Random2));
|
||||
}
|
||||
Radius = std::min(Radius, DBL_MAX);
|
||||
return Radius;
|
||||
}
|
||||
|
||||
G4double GFlashHomoShowerParameterisation::
|
||||
ComputeTau(G4double LongitudinalPosition)
|
||||
G4double GFlashHomoShowerParameterisation::ComputeTau(G4double LongitudinalPosition)
|
||||
{
|
||||
G4double tau = LongitudinalPosition / Tmaxh / X0 //<t> = T* a /(a - 1)
|
||||
* (Alphah-1.00) /Alphah *
|
||||
std::exp(AveLogAlphah)/(std::exp(AveLogAlphah)-1.); //ok
|
||||
G4double tau = LongitudinalPosition / Tmaxh / X0 //<t> = T* a /(a - 1)
|
||||
* (Alphah - 1.00) / Alphah * std::exp(AveLogAlphah)
|
||||
/ (std::exp(AveLogAlphah) - 1.); // ok
|
||||
return tau;
|
||||
}
|
||||
|
||||
void GFlashHomoShowerParameterisation::
|
||||
ComputeRadialParameters(G4double Energy, G4double Tau)
|
||||
void GFlashHomoShowerParameterisation::ComputeRadialParameters(G4double Energy, G4double Tau)
|
||||
{
|
||||
G4double z1 = ParRC1 + ParRC2* std::log(Energy/GeV) ; //ok
|
||||
G4double z2 = ParRC3+ParRC4*Z ; //ok
|
||||
RadiusCore = z1 + z2 * Tau ; //ok
|
||||
G4double z1 = ParRC1 + ParRC2 * std::log(Energy / GeV); // ok
|
||||
G4double z2 = ParRC3 + ParRC4 * Z; // ok
|
||||
RadiusCore = z1 + z2 * Tau; // ok
|
||||
|
||||
G4double p1 = ParWC1+ParWC2*Z; //ok
|
||||
G4double p2 = ParWC3+ParWC4*Z; //ok
|
||||
G4double p3 = ParWC5+ParWC6*std::log(Energy/GeV); //ok
|
||||
G4double p1 = ParWC1 + ParWC2 * Z; // ok
|
||||
G4double p2 = ParWC3 + ParWC4 * Z; // ok
|
||||
G4double p3 = ParWC5 + ParWC6 * std::log(Energy / GeV); // ok
|
||||
|
||||
WeightCore = p1 * std::exp( (p2-Tau)/p3 - std::exp( (p2-Tau) /p3) ); //ok
|
||||
WeightCore = p1 * std::exp((p2 - Tau) / p3 - std::exp((p2 - Tau) / p3)); // ok
|
||||
|
||||
G4double k1 = ParRT1+ParRT2*Z; // ok
|
||||
G4double k2 = ParRT3; // ok
|
||||
G4double k3 = ParRT4; // ok
|
||||
G4double k4 = ParRT5+ParRT6* std::log(Energy/GeV); // ok
|
||||
G4double k1 = ParRT1 + ParRT2 * Z; // ok
|
||||
G4double k2 = ParRT3; // ok
|
||||
G4double k3 = ParRT4; // ok
|
||||
G4double k4 = ParRT5 + ParRT6 * std::log(Energy / GeV); // ok
|
||||
|
||||
RadiusTail = k1*(std::exp(k3*(Tau-k2)) +
|
||||
std::exp(k4*(Tau-k2)) ); //ok
|
||||
RadiusTail = k1 * (std::exp(k3 * (Tau - k2)) + std::exp(k4 * (Tau - k2))); // ok
|
||||
}
|
||||
|
||||
G4double GFlashHomoShowerParameterisation::
|
||||
|
||||
@@ -39,72 +39,68 @@
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
|
||||
GFlashParticleBounds::GFlashParticleBounds()
|
||||
{
|
||||
{
|
||||
// e+e- defaults
|
||||
EMinEneToParametrise = 0.10*GeV;
|
||||
EMaxEneToParametrise = 10000.00*GeV;
|
||||
EEneToKill = 0.1*GeV; // Energie at which electrons are killed
|
||||
EMinEneToParametrise = 0.10 * GeV;
|
||||
EMaxEneToParametrise = 10000.00 * GeV;
|
||||
EEneToKill = 0.1 * GeV; // Energie at which electrons are killed
|
||||
}
|
||||
|
||||
GFlashParticleBounds::~GFlashParticleBounds()
|
||||
{
|
||||
}
|
||||
|
||||
void GFlashParticleBounds::
|
||||
SetMinEneToParametrise(G4ParticleDefinition &particleType, G4double enemin)
|
||||
{
|
||||
if( &particleType == G4Electron::ElectronDefinition()||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
EMinEneToParametrise = enemin;
|
||||
}
|
||||
|
||||
void GFlashParticleBounds::
|
||||
SetMaxEneToParametrise(G4ParticleDefinition &particleType, G4double enemax)
|
||||
void GFlashParticleBounds::SetMinEneToParametrise(G4ParticleDefinition& particleType,
|
||||
G4double enemin)
|
||||
{
|
||||
if( &particleType == G4Electron::ElectronDefinition()||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
EMaxEneToParametrise = enemax;
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
EMinEneToParametrise = enemin;
|
||||
}
|
||||
|
||||
void GFlashParticleBounds::
|
||||
SetEneToKill(G4ParticleDefinition &particleType, G4double enekill)
|
||||
void GFlashParticleBounds::SetMaxEneToParametrise(G4ParticleDefinition& particleType,
|
||||
G4double enemax)
|
||||
{
|
||||
if( &particleType == G4Electron::ElectronDefinition()||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
EEneToKill = enekill;
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
EMaxEneToParametrise = enemax;
|
||||
}
|
||||
|
||||
G4double GFlashParticleBounds::
|
||||
GetMinEneToParametrise(G4ParticleDefinition &particleType)
|
||||
{
|
||||
void GFlashParticleBounds::SetEneToKill(G4ParticleDefinition& particleType, G4double enekill)
|
||||
{
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
EEneToKill = enekill;
|
||||
}
|
||||
|
||||
G4double GFlashParticleBounds::GetMinEneToParametrise(G4ParticleDefinition& particleType)
|
||||
{
|
||||
G4double result = DBL_MAX;
|
||||
if( &particleType == G4Electron::ElectronDefinition()||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
{
|
||||
result = EMinEneToParametrise;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
G4double GFlashParticleBounds::
|
||||
GetMaxEneToParametrise(G4ParticleDefinition &particleType)
|
||||
{
|
||||
G4double result = 0;
|
||||
if( &particleType == G4Electron::ElectronDefinition()||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
{
|
||||
result = EMaxEneToParametrise;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
G4double GFlashParticleBounds::
|
||||
GetEneToKill(G4ParticleDefinition & particleType)
|
||||
G4double GFlashParticleBounds::GetMaxEneToParametrise(G4ParticleDefinition& particleType)
|
||||
{
|
||||
if (&particleType == G4Electron::ElectronDefinition() ||
|
||||
&particleType == G4Positron::PositronDefinition())
|
||||
return EEneToKill;
|
||||
else return (-DBL_MAX);
|
||||
G4double result = 0;
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
{
|
||||
result = EMaxEneToParametrise;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
G4double GFlashParticleBounds::GetEneToKill(G4ParticleDefinition& particleType)
|
||||
{
|
||||
if (&particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition())
|
||||
return EEneToKill;
|
||||
else
|
||||
return (-DBL_MAX);
|
||||
}
|
||||
|
||||
@@ -43,110 +43,136 @@
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
|
||||
GFlashSamplingShowerParameterisation::
|
||||
GFlashSamplingShowerParameterisation(G4Material* aMat1, G4Material* aMat2,
|
||||
G4double dd1, G4double dd2,
|
||||
GFlashSamplingShowerTuning* aPar)
|
||||
GFlashSamplingShowerParameterisation::GFlashSamplingShowerParameterisation(
|
||||
G4Material* aMat1, G4Material* aMat2, G4double dd1, G4double dd2,
|
||||
GFlashSamplingShowerTuning* aPar)
|
||||
: GVFlashShowerParameterisation(),
|
||||
ParAveT2(0.), ParSigLogT1(0.), ParSigLogT2(0.),
|
||||
ParSigLogA1(0.), ParSigLogA2(0.), ParRho1(0.), ParRho2(0.), ParsAveA2(0.),
|
||||
AveLogAlphah(0.), AveLogTmaxh(0.), SigmaLogAlphah(0.), SigmaLogTmaxh(0.),
|
||||
Rhoh(0.), Alphah(0.), Tmaxh(0.), Betah(0.), AveLogAlpha(0.), AveLogTmax(0.),
|
||||
SigmaLogAlpha(0.), SigmaLogTmax(0.), Rho(0.), Alpha(0.), Tmax(0.), Beta(0.)
|
||||
{
|
||||
if(!aPar) {
|
||||
ParAveT2(0.),
|
||||
ParSigLogT1(0.),
|
||||
ParSigLogT2(0.),
|
||||
ParSigLogA1(0.),
|
||||
ParSigLogA2(0.),
|
||||
ParRho1(0.),
|
||||
ParRho2(0.),
|
||||
ParsAveA2(0.),
|
||||
AveLogAlphah(0.),
|
||||
AveLogTmaxh(0.),
|
||||
SigmaLogAlphah(0.),
|
||||
SigmaLogTmaxh(0.),
|
||||
Rhoh(0.),
|
||||
Alphah(0.),
|
||||
Tmaxh(0.),
|
||||
Betah(0.),
|
||||
AveLogAlpha(0.),
|
||||
AveLogTmax(0.),
|
||||
SigmaLogAlpha(0.),
|
||||
SigmaLogTmax(0.),
|
||||
Rho(0.),
|
||||
Alpha(0.),
|
||||
Tmax(0.),
|
||||
Beta(0.)
|
||||
{
|
||||
if (!aPar) {
|
||||
thePar = new GFlashSamplingShowerTuning;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
thePar = aPar;
|
||||
}
|
||||
|
||||
SetMaterial(aMat1,aMat2 );
|
||||
d1=dd1;
|
||||
d2=dd2;
|
||||
SetMaterial(aMat1, aMat2);
|
||||
d1 = dd1;
|
||||
d2 = dd2;
|
||||
|
||||
// Longitudinal Coefficients for a homogenious calo
|
||||
|
||||
// shower max
|
||||
ParAveT1 = thePar->ParAveT1(); // ln (ln y -0.812)
|
||||
ParAveA1 = thePar->ParAveA1(); // ln a (0.81 + (0.458 + 2.26/Z)ln y)
|
||||
ParAveA2 = thePar->ParAveA2();
|
||||
ParAveA3 = thePar->ParAveA3();
|
||||
ParAveT1 = thePar->ParAveT1(); // ln (ln y -0.812)
|
||||
ParAveA1 = thePar->ParAveA1(); // ln a (0.81 + (0.458 + 2.26/Z)ln y)
|
||||
ParAveA2 = thePar->ParAveA2();
|
||||
ParAveA3 = thePar->ParAveA3();
|
||||
// Variance of shower max sampling
|
||||
ParSigLogT1 = thePar->ParsSigLogT1(); // Sigma T1 (-1.4 + 1.26 ln y)**-1 --> bug : these two lines were missing,
|
||||
ParSigLogT1 =
|
||||
thePar
|
||||
->ParsSigLogT1(); // Sigma T1 (-1.4 + 1.26 ln y)**-1 --> bug : these two lines were missing,
|
||||
ParSigLogT2 = thePar->ParsSigLogT2(); // leaving ParSigLogT1, ParSigLogT2 as 0.0
|
||||
// variance of 'alpha'
|
||||
ParSigLogA1 = thePar->ParSigLogA1(); // Sigma a (-0.58 + 0.86 ln y)**-1 --> bug : these two lines were missing
|
||||
ParSigLogA2 = thePar->ParSigLogA2(); // leaving ParSigLogA1 ParSigLogAé as 0.0
|
||||
ParSigLogA1 =
|
||||
thePar
|
||||
->ParSigLogA1(); // Sigma a (-0.58 + 0.86 ln y)**-1 --> bug : these two lines were missing
|
||||
ParSigLogA2 = thePar->ParSigLogA2(); // leaving ParSigLogA1 ParSigLogAé as 0.0
|
||||
// correlation alpha%T
|
||||
ParRho1 = thePar->ParRho1(); // Rho = 0.705 -0.023 ln y --> bug : these two lines were missing,
|
||||
ParRho2 = thePar->ParRho2(); // leaving ParRho1 and ParRho2 being 0.0
|
||||
ParRho1 = thePar->ParRho1(); // Rho = 0.705 -0.023 ln y --> bug : these two lines were missing,
|
||||
ParRho2 = thePar->ParRho2(); // leaving ParRho1 and ParRho2 being 0.0
|
||||
// Sampling
|
||||
ParsAveT1 = thePar->ParsAveT1(); // T_sam = log(exp( log T_hom) + t1*Fs-1 + t2*(1-ehat));
|
||||
ParsAveT2 = thePar->ParsAveT2();
|
||||
ParsAveA1 = thePar->ParsAveA1();
|
||||
ParsAveT1 = thePar->ParsAveT1(); // T_sam = log(exp( log T_hom) + t1*Fs-1 + t2*(1-ehat));
|
||||
ParsAveT2 = thePar->ParsAveT2();
|
||||
ParsAveA1 = thePar->ParsAveA1();
|
||||
// Variance of shower max sampling
|
||||
ParsSigLogT1 = thePar->ParsSigLogT1(); // Sigma T1 (-2.5 + 1.25 ln y)**-1 --> bug ParSigLogT1() was called instead of ParsSigLogT1(); Same for T2.
|
||||
ParsSigLogT1 = thePar->ParsSigLogT1(); // Sigma T1 (-2.5 + 1.25 ln y)**-1 --> bug ParSigLogT1()
|
||||
// was called instead of ParsSigLogT1(); Same for T2.
|
||||
ParsSigLogT2 = thePar->ParsSigLogT2();
|
||||
// variance of 'alpha'
|
||||
ParsSigLogA1 = thePar->ParsSigLogA1(); // Sigma a (-0.82 + 0.79 ln y)**-1 --> bug ParSigLogA1() was called instead of ParsSigLogA1(); Same for A2
|
||||
ParsSigLogA1 = thePar->ParsSigLogA1(); // Sigma a (-0.82 + 0.79 ln y)**-1 --> bug ParSigLogA1()
|
||||
// was called instead of ParsSigLogA1(); Same for A2
|
||||
ParsSigLogA2 = thePar->ParsSigLogA2();
|
||||
// correlation alpha%T
|
||||
ParsRho1 = thePar->ParsRho1(); // Rho = 0.784 -0.023 ln y --> bug was using ParRho1() and ParRho2()
|
||||
ParsRho2 = thePar->ParsRho2();
|
||||
ParsRho1 =
|
||||
thePar->ParsRho1(); // Rho = 0.784 -0.023 ln y --> bug was using ParRho1() and ParRho2()
|
||||
ParsRho2 = thePar->ParsRho2();
|
||||
|
||||
// Radial Coefficients
|
||||
// r_C (tau)= z_1 +z_2 tau
|
||||
// r_t (tau)= k1 (std::exp (k3(tau -k2 ))+std::exp (k_4 (tau- k_2))))
|
||||
ParRC1 = thePar->ParRC1(); // z_1 = 0.0251 + 0.00319 ln E
|
||||
ParRC2 = thePar->ParRC2();
|
||||
ParRC3 = thePar->ParRC3(); // z_2 = 0.1162 + - 0.000381 Z
|
||||
ParRC4 = thePar->ParRC4();
|
||||
ParRC1 = thePar->ParRC1(); // z_1 = 0.0251 + 0.00319 ln E
|
||||
ParRC2 = thePar->ParRC2();
|
||||
ParRC3 = thePar->ParRC3(); // z_2 = 0.1162 + - 0.000381 Z
|
||||
ParRC4 = thePar->ParRC4();
|
||||
|
||||
ParWC1 = thePar->ParWC1();
|
||||
ParWC2 = thePar->ParWC2();
|
||||
ParWC3 = thePar->ParWC3();
|
||||
ParWC4 = thePar->ParWC4();
|
||||
ParWC5 = thePar->ParWC5();
|
||||
ParWC5 = thePar->ParWC5();
|
||||
ParWC6 = thePar->ParWC6();
|
||||
ParRT1 = thePar->ParRT1();
|
||||
ParRT2 = thePar->ParRT2();
|
||||
ParRT3 = thePar->ParRT3();
|
||||
ParRT4 = thePar->ParRT4();
|
||||
ParRT4 = thePar->ParRT4();
|
||||
ParRT5 = thePar->ParRT5();
|
||||
ParRT6 = thePar->ParRT6();
|
||||
|
||||
//additional sampling parameter
|
||||
ParsRC1= thePar->ParsRC1();
|
||||
ParsRC2= thePar->ParsRC2();
|
||||
ParsWC1= thePar->ParsWC1();
|
||||
ParsWC2= thePar->ParsWC2();
|
||||
ParsRT1= thePar->ParsRT1();
|
||||
ParsRT2= thePar->ParsRT2();
|
||||
// additional sampling parameter
|
||||
ParsRC1 = thePar->ParsRC1();
|
||||
ParsRC2 = thePar->ParsRC2();
|
||||
ParsWC1 = thePar->ParsWC1();
|
||||
ParsWC2 = thePar->ParsWC2();
|
||||
ParsRT1 = thePar->ParsRT1();
|
||||
ParsRT2 = thePar->ParsRT2();
|
||||
|
||||
// Coeff for fluctuedted radial profiles for a sampling media
|
||||
ParsSpotT1 = thePar->ParSpotT1(); // T_spot = T_hom =(0.698 + 0.00212)
|
||||
ParsSpotT2 = thePar->ParSpotT2();
|
||||
ParsSpotA1 = thePar->ParSpotA1(); // a_spot= a_hom (0.639 + 0.00334)
|
||||
ParsSpotA2 = thePar->ParSpotA2();
|
||||
ParsSpotN1 = thePar->ParSpotN1(); // N_Spot 93 * ln(Z) E ** 0.876
|
||||
ParsSpotN2 = thePar->ParSpotN2();
|
||||
SamplingResolution = thePar->SamplingResolution();
|
||||
ConstantResolution = thePar->ConstantResolution();
|
||||
NoiseResolution = thePar->NoiseResolution();
|
||||
ParsSpotT1 = thePar->ParSpotT1(); // T_spot = T_hom =(0.698 + 0.00212)
|
||||
ParsSpotT2 = thePar->ParSpotT2();
|
||||
ParsSpotA1 = thePar->ParSpotA1(); // a_spot= a_hom (0.639 + 0.00334)
|
||||
ParsSpotA2 = thePar->ParSpotA2();
|
||||
ParsSpotN1 = thePar->ParSpotN1(); // N_Spot 93 * ln(Z) E ** 0.876
|
||||
ParsSpotN2 = thePar->ParSpotN2();
|
||||
SamplingResolution = thePar->SamplingResolution();
|
||||
ConstantResolution = thePar->ConstantResolution();
|
||||
NoiseResolution = thePar->NoiseResolution();
|
||||
|
||||
// Inits
|
||||
NSpot = 0.00;
|
||||
AlphaNSpot = 0.00;
|
||||
TNSpot = 0.00;
|
||||
BetaNSpot = 0.00;
|
||||
RadiusCore = 0.00;
|
||||
WeightCore = 0.00;
|
||||
RadiusTail = 0.00;
|
||||
NSpot = 0.00;
|
||||
AlphaNSpot = 0.00;
|
||||
TNSpot = 0.00;
|
||||
BetaNSpot = 0.00;
|
||||
RadiusCore = 0.00;
|
||||
WeightCore = 0.00;
|
||||
RadiusTail = 0.00;
|
||||
ComputeZAX0EFFetc();
|
||||
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
G4cout << " - GFlashSamplingShowerParameterisation::Constructor - " << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
@@ -158,26 +184,27 @@ GFlashSamplingShowerParameterisation::~GFlashSamplingShowerParameterisation()
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void GFlashSamplingShowerParameterisation::
|
||||
SetMaterial(G4Material *mat1, G4Material *mat2)
|
||||
void GFlashSamplingShowerParameterisation::SetMaterial(G4Material* mat1, G4Material* mat2)
|
||||
{
|
||||
G4double Es = 21*MeV;
|
||||
material1= mat1;
|
||||
const G4double Es = 21.2 * MeV;
|
||||
material1 = mat1;
|
||||
Z1 = GetEffZ(material1);
|
||||
A1 = GetEffA(material1);
|
||||
density1 = material1->GetDensity();
|
||||
X01 = material1->GetRadlen();
|
||||
Ec1 = 2.66 * std::pow((X01 * Z1 / A1),1.1);
|
||||
Rm1 = X01*Es/Ec1;
|
||||
X01 = material1->GetRadlen();
|
||||
Ec1 = 2.66 * std::pow((X01 * Z1 / A1), 1.1);
|
||||
// Ec1 = 610.0 * MeV / (Z1 + 1.24);
|
||||
Rm1 = X01 * Es / Ec1;
|
||||
|
||||
material2= mat2;
|
||||
material2 = mat2;
|
||||
Z2 = GetEffZ(material2);
|
||||
A2 = GetEffA(material2);
|
||||
density2 = material2->GetDensity();
|
||||
X02 = material2->GetRadlen();
|
||||
Ec2 = 2.66 * std::pow((X02 * Z2 / A2),1.1);
|
||||
Rm2 = X02*Es/Ec2;
|
||||
// PrintMaterial();
|
||||
X02 = material2->GetRadlen();
|
||||
Ec2 = 2.66 * std::pow((X02 * Z2 / A2), 1.1);
|
||||
// Ec2 = 610.0 * MeV / (Z2 + 1.24);
|
||||
Rm2 = X02 * Es / Ec2;
|
||||
// PrintMaterial();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
@@ -187,154 +214,158 @@ void GFlashSamplingShowerParameterisation::ComputeZAX0EFFetc()
|
||||
G4cout << "/************ ComputeZAX0EFFetc ************/" << G4endl;
|
||||
G4cout << " - GFlashSamplingShowerParameterisation::Material - " << G4endl;
|
||||
|
||||
G4double Es = 21*MeV; //constant
|
||||
const G4double Es = 21.2 * MeV;
|
||||
|
||||
// material and geometry parameters for a sampling calorimeter
|
||||
G4double denominator = (d1*density1 + d2*density2);
|
||||
G4double W1 = (d1*density1) / denominator;
|
||||
G4double W2 = (d2*density2) / denominator;
|
||||
Zeff = ( W1*Z1 ) + ( W2*Z2 ); //X0*Es/Ec;
|
||||
Aeff = ( W1*A1 ) + ( W2*A2 );
|
||||
Rhoeff = ( ( d1*density1 ) + ( d2*density2 ) ) / ( d1 + d2 ); // --> was G4double ( d2 + d1 );
|
||||
X0eff = (W1 * Rhoeff) / (X01 * density1) + (W2 * Rhoeff) / (X02 * density2 );
|
||||
X0eff = 1./ X0eff;
|
||||
Rmeff = 1./ ( ( ((W1*Ec1)/X01) + ((W2*Ec2)/X02) ) / Es ) ;
|
||||
Eceff = X0eff * ( (W1*Ec1)/X01 + (W2*Ec2)/X02 );
|
||||
Fs = X0eff/(d1+d2);// --> was G4double ((d1/mm )+(d2/mm) ); Can't understand if dividing by mm makes sense... looks weird.
|
||||
ehat = ( 1. / ( 1 + 0.007*(Z1- Z2) ) );
|
||||
G4double denominator = (d1 * density1 + d2 * density2);
|
||||
G4double W1 = (d1 * density1) / denominator;
|
||||
G4double W2 = (d2 * density2) / denominator;
|
||||
Zeff = (W1 * Z1) + (W2 * Z2); // X0*Es/Ec;
|
||||
Aeff = (W1 * A1) + (W2 * A2);
|
||||
Rhoeff = ((d1 * density1) + (d2 * density2)) / (d1 + d2); // --> was G4double ( d2 + d1 );
|
||||
X0eff = (W1 * Rhoeff) / (X01 * density1) + (W2 * Rhoeff) / (X02 * density2);
|
||||
X0eff = 1. / X0eff;
|
||||
Rmeff = 1. / ((((W1 * Ec1) / X01) + ((W2 * Ec2) / X02)) / Es);
|
||||
Eceff = X0eff * ((W1 * Ec1) / X01 + (W2 * Ec2) / X02);
|
||||
Fs = X0eff / (d1 + d2); // --> was G4double ((d1/mm )+(d2/mm) ); Can't understand if dividing by
|
||||
// mm makes sense... looks weird.
|
||||
ehat = (1. / (1 + 0.007 * (Z1 - Z2)));
|
||||
|
||||
G4cout << "W1= " << W1 << G4endl;
|
||||
G4cout << "W2= " << W2 << G4endl;
|
||||
G4cout << "effective quantities Zeff = "<<Zeff<< G4endl;
|
||||
G4cout << "effective quantities Aeff = "<<Aeff<< G4endl;
|
||||
G4cout << "effective quantities Rhoeff = "<<Rhoeff/g *cm3<<" g/cm3" << G4endl;
|
||||
G4cout << "effective quantities X0eff = "<<X0eff/cm <<" cm" << G4endl;
|
||||
G4cout << "effective quantities Zeff = " << Zeff << G4endl;
|
||||
G4cout << "effective quantities Aeff = " << Aeff << G4endl;
|
||||
G4cout << "effective quantities Rhoeff = " << Rhoeff / g * cm3 << " g/cm3" << G4endl;
|
||||
G4cout << "effective quantities X0eff = " << X0eff / cm << " cm" << G4endl;
|
||||
|
||||
X0eff = X0eff * Rhoeff;
|
||||
|
||||
G4cout << "effective quantities X0eff = "<<X0eff/g*cm2 <<" g/cm2" << G4endl;
|
||||
X0eff = X0eff /Rhoeff;
|
||||
G4cout << "effective quantities RMeff = "<<Rmeff/cm<<" cm" << G4endl;
|
||||
Rmeff = Rmeff* Rhoeff;
|
||||
G4cout << "effective quantities RMeff = "<<Rmeff/g *cm2<<" g/cm2" << G4endl;
|
||||
Rmeff = Rmeff/ Rhoeff;
|
||||
G4cout << "effective quantities Eceff = "<<Eceff/MeV<< " MeV"<< G4endl;
|
||||
G4cout << "effective quantities Fs = "<<Fs<<G4endl;
|
||||
G4cout << "effective quantities ehat = "<<ehat<<G4endl;
|
||||
G4cout << "/********************************************/ " <<G4endl;
|
||||
G4cout << "effective quantities X0eff = " << X0eff / g * cm2 << " g/cm2" << G4endl;
|
||||
X0eff = X0eff / Rhoeff;
|
||||
G4cout << "effective quantities RMeff = " << Rmeff / cm << " cm" << G4endl;
|
||||
Rmeff = Rmeff * Rhoeff;
|
||||
G4cout << "effective quantities RMeff = " << Rmeff / g * cm2 << " g/cm2" << G4endl;
|
||||
Rmeff = Rmeff / Rhoeff;
|
||||
G4cout << "effective quantities Eceff = " << Eceff / MeV << " MeV" << G4endl;
|
||||
G4cout << "effective quantities Fs = " << Fs << G4endl;
|
||||
G4cout << "effective quantities ehat = " << ehat << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void GFlashSamplingShowerParameterisation::
|
||||
GenerateLongitudinalProfile(G4double Energy)
|
||||
void GFlashSamplingShowerParameterisation::GenerateLongitudinalProfile(G4double Energy)
|
||||
{
|
||||
if ((material1==0) || (material2 ==0))
|
||||
{
|
||||
if ((material1 == 0) || (material2 == 0)) {
|
||||
G4Exception("GFlashSamplingShowerParameterisation::GenerateLongitudinalProfile()",
|
||||
"InvalidSetup", FatalException, "No material initialized!");
|
||||
}
|
||||
G4double y = Energy/Eceff;
|
||||
ComputeLongitudinalParameters(y);
|
||||
}
|
||||
G4double y = Energy / Eceff;
|
||||
ComputeLongitudinalParameters(y);
|
||||
GenerateEnergyProfile(y);
|
||||
GenerateNSpotProfile(y);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void
|
||||
GFlashSamplingShowerParameterisation::ComputeLongitudinalParameters(G4double y)
|
||||
void GFlashSamplingShowerParameterisation::ComputeLongitudinalParameters(G4double y)
|
||||
{
|
||||
AveLogTmaxh = std::log( std::max( ParAveT1 + std::log(y), 0.1 ) ); // ok
|
||||
AveLogAlphah = std::log( std::max( ParAveA1 + (ParAveA2+ParAveA3/Zeff)*std::log(y), 0.1 ) ); // ok
|
||||
AveLogTmaxh = std::log(std::max(ParAveT1 + std::log(y), 0.1)); // ok
|
||||
AveLogAlphah =
|
||||
std::log(std::max(ParAveA1 + (ParAveA2 + ParAveA3 / Zeff) * std::log(y), 0.1)); // ok
|
||||
// hom
|
||||
SigmaLogTmaxh = std::min( 0.5, 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y) ) ); // ok
|
||||
SigmaLogAlphah = std::min( 0.5, 1.00/( ParSigLogA1 + ParSigLogA2*std::log(y) ) ); // ok
|
||||
Rhoh = ParRho1 + ParRho2*std::log(y); //ok
|
||||
// if sampling
|
||||
AveLogTmax = std::max( 0.1, std::log(std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat)) ); // ok
|
||||
AveLogAlpha = std::max( 0.1, std::log(std::exp(AveLogAlphah) + ParsAveA1/Fs) ); // ok
|
||||
SigmaLogTmaxh = std::min(0.5, 1.00 / (ParSigLogT1 + ParSigLogT2 * std::log(y))); // ok
|
||||
SigmaLogAlphah = std::min(0.5, 1.00 / (ParSigLogA1 + ParSigLogA2 * std::log(y))); // ok
|
||||
Rhoh = ParRho1 + ParRho2 * std::log(y); // ok
|
||||
// if sampling
|
||||
AveLogTmax =
|
||||
std::max(0.1, std::log(std::exp(AveLogTmaxh) + ParsAveT1 / Fs + ParsAveT2 * (1 - ehat))); // ok
|
||||
AveLogAlpha = std::max(0.1, std::log(std::exp(AveLogAlphah) + ParsAveA1 / Fs)); // ok
|
||||
//
|
||||
SigmaLogTmax = std::min( 0.5, 1.00 / (ParsSigLogT1 + ParsSigLogT2*std::log(y)) ); // ok
|
||||
SigmaLogAlpha = std::min( 0.5, 1.00 / (ParsSigLogA1 + ParsSigLogA2*std::log(y)) ); // ok
|
||||
Rho = ParsRho1 + ParsRho2*std::log(y); // ok
|
||||
|
||||
SigmaLogTmax = std::min(0.5, 1.00 / (ParsSigLogT1 + ParsSigLogT2 * std::log(y))); // ok
|
||||
SigmaLogAlpha = std::min(0.5, 1.00 / (ParsSigLogA1 + ParsSigLogA2 * std::log(y))); // ok
|
||||
Rho = ParsRho1 + ParsRho2 * std::log(y); // ok
|
||||
|
||||
if (0) {
|
||||
G4cout << " y = " << y << G4endl;
|
||||
G4cout << " std::log(std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat)) = "
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1/Fs << " + " << ParsAveT2*(1-ehat) << ") = "
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1 << "/" << Fs << " + " << ParsAveT2 << "*" << (1-ehat) << ") = "
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat) << ")" << G4endl;
|
||||
G4cout << " AveLogTmaxh " << AveLogTmaxh << G4endl;
|
||||
G4cout << " AveLogAlphah " << AveLogAlphah << G4endl;
|
||||
G4cout << " SigmaLogTmaxh " << SigmaLogTmaxh << G4endl;
|
||||
G4cout << " 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y) ) = " << 1.00 << "/" << ( ParSigLogT1 + ParSigLogT2*std::log(y) ) << " = "
|
||||
<< 1.00 << "/" << "(" << ParSigLogT1 << " + " << ParSigLogT2*std::log(y) << " ) = "
|
||||
<< 1.00 << "/" << "(" << ParSigLogT1 << " + " << ParSigLogT2 << "*" << std::log(y) << " ) "
|
||||
<< G4endl;
|
||||
G4cout << " SigmaLogAlphah " << SigmaLogAlphah << G4endl;
|
||||
G4cout << " Rhoh " << Rhoh << G4endl;
|
||||
G4cout << " AveLogTmax " << AveLogTmax << G4endl;
|
||||
G4cout << " AveLogAlpha " << AveLogAlpha << G4endl;
|
||||
G4cout << " SigmaLogTmax " << SigmaLogTmax << G4endl;
|
||||
G4cout << " SigmaLogAlpha " << SigmaLogAlpha << G4endl;
|
||||
G4cout << " Rho " << Rho << G4endl;
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1 / Fs << " + "
|
||||
<< ParsAveT2 * (1 - ehat) << ") = "
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1 << "/" << Fs << " + "
|
||||
<< ParsAveT2 << "*" << (1 - ehat) << ") = "
|
||||
<< " std::log(" << std::exp(AveLogTmaxh) + ParsAveT1 / Fs + ParsAveT2 * (1 - ehat) << ")"
|
||||
<< G4endl;
|
||||
G4cout << " AveLogTmaxh " << AveLogTmaxh << G4endl;
|
||||
G4cout << " AveLogAlphah " << AveLogAlphah << G4endl;
|
||||
G4cout << " SigmaLogTmaxh " << SigmaLogTmaxh << G4endl;
|
||||
G4cout << " 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y) ) = " << 1.00 << "/"
|
||||
<< (ParSigLogT1 + ParSigLogT2 * std::log(y)) << " = " << 1.00 << "/" << "("
|
||||
<< ParSigLogT1 << " + " << ParSigLogT2 * std::log(y) << " ) = " << 1.00 << "/" << "("
|
||||
<< ParSigLogT1 << " + " << ParSigLogT2 << "*" << std::log(y) << " ) " << G4endl;
|
||||
G4cout << " SigmaLogAlphah " << SigmaLogAlphah << G4endl;
|
||||
G4cout << " Rhoh " << Rhoh << G4endl;
|
||||
G4cout << " AveLogTmax " << AveLogTmax << G4endl;
|
||||
G4cout << " AveLogAlpha " << AveLogAlpha << G4endl;
|
||||
G4cout << " SigmaLogTmax " << SigmaLogTmax << G4endl;
|
||||
G4cout << " SigmaLogAlpha " << SigmaLogAlpha << G4endl;
|
||||
G4cout << " Rho " << Rho << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void GFlashSamplingShowerParameterisation::GenerateEnergyProfile(G4double /* y */)
|
||||
{
|
||||
G4double Correlation1 = std::sqrt( (1+Rho )/2 );
|
||||
G4double Correlation2 = std::sqrt( (1-Rho )/2 );
|
||||
G4double Correlation1h = std::sqrt( (1+Rhoh)/2 );
|
||||
G4double Correlation2h = std::sqrt( (1-Rhoh)/2 );
|
||||
{
|
||||
G4double Correlation1 = std::sqrt((1 + Rho) / 2);
|
||||
G4double Correlation2 = std::sqrt((1 - Rho) / 2);
|
||||
G4double Correlation1h = std::sqrt((1 + Rhoh) / 2);
|
||||
G4double Correlation2h = std::sqrt((1 - Rhoh) / 2);
|
||||
G4double Random1 = G4RandGauss::shoot();
|
||||
G4double Random2 = G4RandGauss::shoot();
|
||||
|
||||
Tmax = std::max( 1., std::exp( AveLogTmax + SigmaLogTmax * (Correlation1*Random1 + Correlation2*Random2) ) );
|
||||
Alpha = std::max( 1.1, std::exp( AveLogAlpha + SigmaLogAlpha * (Correlation1*Random1 - Correlation2*Random2) ) );
|
||||
Beta = (Alpha-1.00)/Tmax;
|
||||
//Parameters for Enenrgy Profile including correaltion and sigmas
|
||||
Tmaxh = std::exp( AveLogTmaxh + SigmaLogTmaxh *
|
||||
(Correlation1h*Random1 + Correlation2h*Random2) );
|
||||
Alphah = std::exp( AveLogAlphah + SigmaLogAlphah *
|
||||
(Correlation1h*Random1 - Correlation2h*Random2) );
|
||||
Betah = (Alphah-1.00)/Tmaxh;
|
||||
Tmax = std::max(
|
||||
1., std::exp(AveLogTmax + SigmaLogTmax * (Correlation1 * Random1 + Correlation2 * Random2)));
|
||||
Alpha = std::max(
|
||||
1.1, std::exp(AveLogAlpha + SigmaLogAlpha * (Correlation1 * Random1 - Correlation2 * Random2)));
|
||||
Beta = (Alpha - 1.00) / Tmax;
|
||||
// Parameters for Enenrgy Profile including correaltion and sigmas
|
||||
Tmaxh =
|
||||
std::exp(AveLogTmaxh + SigmaLogTmaxh * (Correlation1h * Random1 + Correlation2h * Random2));
|
||||
Alphah =
|
||||
std::exp(AveLogAlphah + SigmaLogAlphah * (Correlation1h * Random1 - Correlation2h * Random2));
|
||||
Betah = (Alphah - 1.00) / Tmaxh;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void GFlashSamplingShowerParameterisation::GenerateNSpotProfile(const G4double y)
|
||||
{
|
||||
TNSpot = Tmaxh * (ParsSpotT1+ParsSpotT2*Zeff); //ok.
|
||||
TNSpot = std::max(0.5,Tmaxh * (ParsSpotT1+ParsSpotT2*Zeff));
|
||||
AlphaNSpot = Alphah * (ParsSpotA1+ParsSpotA2*Zeff);
|
||||
BetaNSpot = (AlphaNSpot-1.00)/TNSpot; // ok
|
||||
NSpot = ParsSpotN1 /SamplingResolution * std::pow(y*Eceff/GeV,ParsSpotN2 );
|
||||
TNSpot = Tmaxh * (ParsSpotT1 + ParsSpotT2 * Zeff); // ok.
|
||||
TNSpot = std::max(0.5, Tmaxh * (ParsSpotT1 + ParsSpotT2 * Zeff));
|
||||
AlphaNSpot = Alphah * (ParsSpotA1 + ParsSpotA2 * Zeff);
|
||||
BetaNSpot = (AlphaNSpot - 1.00) / TNSpot; // ok
|
||||
NSpot = ParsSpotN1 / SamplingResolution * std::pow(y * Eceff / GeV, ParsSpotN2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
G4double
|
||||
GFlashSamplingShowerParameterisation::
|
||||
ApplySampling(const G4double DEne, const G4double )
|
||||
G4double GFlashSamplingShowerParameterisation::ApplySampling(const G4double DEne, const G4double)
|
||||
{
|
||||
G4double DEneFluctuated = DEne;
|
||||
G4double Resolution = std::pow(SamplingResolution,2);
|
||||
G4double Resolution = std::pow(SamplingResolution, 2);
|
||||
|
||||
// +pow(NoiseResolution,2)/ //@@@@@@@@ FIXME
|
||||
// +pow(NoiseResolution,2)/ //@@@@@@@@ FIXME
|
||||
// Energy*(1.*MeV)+
|
||||
// pow(ConstantResolution,2)*
|
||||
// Energy/(1.*MeV);
|
||||
|
||||
if(Resolution >0.0 && DEne > 0.00)
|
||||
{
|
||||
G4float x1=DEne/Resolution;
|
||||
G4float x2 = G4RandGamma::shoot(x1, 1.0)*Resolution;
|
||||
DEneFluctuated=x2;
|
||||
if (Resolution > 0.0 && DEne > 0.00) {
|
||||
// G4float x1 = DEne / Resolution;
|
||||
// G4float x2 = G4RandGamma::shoot(x1, 1.0) * Resolution;
|
||||
// DEneFluctuated = x2;
|
||||
G4double x1 = DEne / Resolution;
|
||||
G4double x2 = 1.0 / Resolution;
|
||||
DEneFluctuated = G4RandGamma::shoot(x1, x2);
|
||||
}
|
||||
return DEneFluctuated;
|
||||
}
|
||||
@@ -354,85 +385,78 @@ IntegrateEneLongitudinal(G4double LongitudinalStep)
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
G4double GFlashSamplingShowerParameterisation::
|
||||
IntegrateNspLongitudinal(G4double LongitudinalStep)
|
||||
G4double GFlashSamplingShowerParameterisation::IntegrateNspLongitudinal(G4double LongitudinalStep)
|
||||
{
|
||||
G4double LongitudinalStepInX0 = LongitudinalStep / X0eff;
|
||||
G4float x1 = BetaNSpot*LongitudinalStepInX0;
|
||||
G4double LongitudinalStepInX0 = LongitudinalStep / X0eff;
|
||||
G4float x1 = BetaNSpot * LongitudinalStepInX0;
|
||||
G4float x2 = AlphaNSpot;
|
||||
G4float x3 = gam(x1,x2);
|
||||
G4float x3 = gam(x1, x2);
|
||||
G4double DNsp = x3;
|
||||
return DNsp;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
G4double GFlashSamplingShowerParameterisation::
|
||||
GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition)
|
||||
G4double GFlashSamplingShowerParameterisation::GenerateRadius(G4int ispot, G4double Energy,
|
||||
G4double LongitudinalPosition)
|
||||
{
|
||||
if(ispot < 1)
|
||||
{
|
||||
if (ispot < 1) {
|
||||
// Determine lateral parameters in the middle of the step.
|
||||
// They depend on energy & position along step
|
||||
//
|
||||
G4double Tau = ComputeTau(LongitudinalPosition);
|
||||
ComputeRadialParameters(Energy,Tau);
|
||||
ComputeRadialParameters(Energy, Tau);
|
||||
}
|
||||
|
||||
|
||||
G4double Radius;
|
||||
G4double Random1 = G4UniformRand();
|
||||
G4double Random2 = G4UniformRand();
|
||||
if(Random1 <WeightCore) //WeightCore = p < w_i
|
||||
G4double Random2 = G4UniformRand();
|
||||
if (Random1 < WeightCore) // WeightCore = p < w_i
|
||||
{
|
||||
Radius = Rmeff * RadiusCore * std::sqrt( Random2/(1. - Random2) );
|
||||
Radius = Rmeff * RadiusCore * std::sqrt(Random2 / (1. - Random2));
|
||||
}
|
||||
else
|
||||
{
|
||||
Radius = Rmeff * RadiusTail * std::sqrt( Random2/(1. - Random2) );
|
||||
}
|
||||
Radius = std::min(Radius,DBL_MAX);
|
||||
else {
|
||||
Radius = Rmeff * RadiusTail * std::sqrt(Random2 / (1. - Random2));
|
||||
}
|
||||
Radius = std::min(Radius, DBL_MAX);
|
||||
return Radius;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
G4double
|
||||
GFlashSamplingShowerParameterisation::
|
||||
ComputeTau(G4double LongitudinalPosition)
|
||||
G4double GFlashSamplingShowerParameterisation::ComputeTau(G4double LongitudinalPosition)
|
||||
{
|
||||
G4double tau = LongitudinalPosition / Tmax/ X0eff //<t> = T* a /(a - 1)
|
||||
* (Alpha-1.00) /Alpha
|
||||
* std::exp(AveLogAlpha)/(std::exp(AveLogAlpha)-1.); //ok
|
||||
G4double tau = LongitudinalPosition / Tmax / X0eff //<t> = T* a /(a - 1)
|
||||
* (Alpha - 1.00) / Alpha * std::exp(AveLogAlpha)
|
||||
/ (std::exp(AveLogAlpha) - 1.); // ok
|
||||
return tau;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void GFlashSamplingShowerParameterisation::
|
||||
ComputeRadialParameters(G4double Energy, G4double Tau)
|
||||
void GFlashSamplingShowerParameterisation::ComputeRadialParameters(G4double Energy, G4double Tau)
|
||||
{
|
||||
G4double z1 = ParRC1 + ParRC2* std::log(Energy/GeV); //ok
|
||||
G4double z2 = ParRC3+ParRC4*Zeff; //ok
|
||||
RadiusCore = z1 + z2 * Tau; //ok
|
||||
G4double p1 = ParWC1+ParWC2*Zeff; //ok
|
||||
G4double p2 = ParWC3+ParWC4*Zeff; //ok
|
||||
G4double p3 = ParWC5+ParWC6*std::log(Energy/GeV); //ok
|
||||
WeightCore = p1 * std::exp( (p2-Tau)/p3- std::exp( (p2-Tau) /p3) ); //ok
|
||||
|
||||
G4double k1 = ParRT1+ParRT2*Zeff; // ok
|
||||
G4double k2 = ParRT3; // ok
|
||||
G4double k3 = ParRT4; // ok
|
||||
G4double k4 = ParRT5+ParRT6* std::log(Energy/GeV); // ok
|
||||
|
||||
RadiusTail = k1*(std::exp(k3*(Tau-k2))
|
||||
+ std::exp(k4*(Tau-k2)) ); //ok
|
||||
G4double z1 = ParRC1 + ParRC2 * std::log(Energy / GeV); // ok
|
||||
G4double z2 = ParRC3 + ParRC4 * Zeff; // ok
|
||||
RadiusCore = z1 + z2 * Tau; // ok
|
||||
G4double p1 = ParWC1 + ParWC2 * Zeff; // ok
|
||||
G4double p2 = ParWC3 + ParWC4 * Zeff; // ok
|
||||
G4double p3 = ParWC5 + ParWC6 * std::log(Energy / GeV); // ok
|
||||
WeightCore = p1 * std::exp((p2 - Tau) / p3 - std::exp((p2 - Tau) / p3)); // ok
|
||||
|
||||
// sampling calorimeter
|
||||
G4double k1 = ParRT1 + ParRT2 * Zeff; // ok
|
||||
G4double k2 = ParRT3; // ok
|
||||
G4double k3 = ParRT4; // ok
|
||||
G4double k4 = ParRT5 + ParRT6 * std::log(Energy / GeV); // ok
|
||||
|
||||
RadiusCore = RadiusCore + ParsRC1*(1-ehat) + ParsRC2/Fs*std::exp(-Tau); //ok
|
||||
WeightCore = WeightCore + (1-ehat)
|
||||
* (ParsWC1+ParsWC2/Fs * std::exp(-std::pow((Tau-1.),2))); //ok
|
||||
RadiusTail = RadiusTail + (1-ehat)* ParsRT1+ ParsRT2/Fs *std::exp(-Tau); //ok
|
||||
RadiusTail = k1 * (std::exp(k3 * (Tau - k2)) + std::exp(k4 * (Tau - k2))); // ok
|
||||
|
||||
// sampling calorimeter
|
||||
|
||||
RadiusCore = RadiusCore + ParsRC1 * (1 - ehat) + ParsRC2 / Fs * std::exp(-Tau); // ok
|
||||
WeightCore =
|
||||
WeightCore + (1 - ehat) * (ParsWC1 + ParsWC2 / Fs * std::exp(-std::pow((Tau - 1.), 2))); // ok
|
||||
RadiusTail = RadiusTail + (1 - ehat) * ParsRT1 + ParsRT2 / Fs * std::exp(-Tau); // ok
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@@ -52,28 +52,24 @@
|
||||
#include "GFlashSamplingShowerParameterisation.hh"
|
||||
#include "GFlashEnergySpot.hh"
|
||||
|
||||
|
||||
GFlashShowerModel::GFlashShowerModel(G4String modelName,
|
||||
G4Envelope* envelope)
|
||||
: G4VFastSimulationModel(modelName, envelope),
|
||||
PBound(0), Parameterisation(0), HMaker(0)
|
||||
GFlashShowerModel::GFlashShowerModel(G4String modelName, G4Envelope* envelope)
|
||||
: G4VFastSimulationModel(modelName, envelope), PBound(0), Parameterisation(0), HMaker(0)
|
||||
{
|
||||
FlagParamType = 0;
|
||||
FlagParticleContainment = 1;
|
||||
FlagParamType = 0;
|
||||
FlagParticleContainment = 1;
|
||||
StepInX0 = 0.1;
|
||||
EnergyStop = 0.0;
|
||||
Messenger = new GFlashShowerModelMessenger(this);
|
||||
Messenger = new GFlashShowerModelMessenger(this);
|
||||
}
|
||||
|
||||
GFlashShowerModel::GFlashShowerModel(G4String modelName)
|
||||
: G4VFastSimulationModel(modelName),
|
||||
PBound(0), Parameterisation(0), HMaker(0)
|
||||
: G4VFastSimulationModel(modelName), PBound(0), Parameterisation(0), HMaker(0)
|
||||
{
|
||||
FlagParamType =1;
|
||||
FlagParticleContainment = 1;
|
||||
StepInX0 = 0.1;
|
||||
FlagParamType = 1;
|
||||
FlagParticleContainment = 1;
|
||||
StepInX0 = 0.1;
|
||||
EnergyStop = 0.0;
|
||||
Messenger = new GFlashShowerModelMessenger(this);
|
||||
Messenger = new GFlashShowerModelMessenger(this);
|
||||
}
|
||||
|
||||
GFlashShowerModel::~GFlashShowerModel()
|
||||
@@ -81,252 +77,220 @@ GFlashShowerModel::~GFlashShowerModel()
|
||||
delete Messenger;
|
||||
}
|
||||
|
||||
G4bool
|
||||
GFlashShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
|
||||
{
|
||||
return
|
||||
&particleType == G4Electron::ElectronDefinition() ||
|
||||
&particleType == G4Positron::PositronDefinition();
|
||||
G4bool GFlashShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
|
||||
{
|
||||
return &particleType == G4Electron::ElectronDefinition()
|
||||
|| &particleType == G4Positron::PositronDefinition();
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Checks whether conditions of fast parameterisation are fullfilled */
|
||||
/**********************************************************************/
|
||||
|
||||
G4bool GFlashShowerModel::ModelTrigger(const G4FastTrack & fastTrack )
|
||||
G4bool GFlashShowerModel::ModelTrigger(const G4FastTrack& fastTrack)
|
||||
|
||||
{
|
||||
G4bool select = false;
|
||||
if(FlagParamType != 0)
|
||||
{
|
||||
G4double ParticleEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
|
||||
G4ParticleDefinition &ParticleType =
|
||||
*(fastTrack.GetPrimaryTrack()->GetDefinition());
|
||||
if(ParticleEnergy > PBound->GetMinEneToParametrise(ParticleType) &&
|
||||
ParticleEnergy < PBound->GetMaxEneToParametrise(ParticleType) )
|
||||
if (FlagParamType != 0) {
|
||||
G4double ParticleEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
|
||||
G4ParticleDefinition& ParticleType = *(fastTrack.GetPrimaryTrack()->GetDefinition());
|
||||
if (ParticleEnergy > PBound->GetMinEneToParametrise(ParticleType)
|
||||
&& ParticleEnergy < PBound->GetMaxEneToParametrise(ParticleType))
|
||||
{
|
||||
// check conditions depending on particle flavour
|
||||
// performance to be optimized @@@@@@@
|
||||
Parameterisation->GenerateLongitudinalProfile(ParticleEnergy);
|
||||
select = CheckParticleDefAndContainment(fastTrack);
|
||||
if (select) EnergyStop= PBound->GetEneToKill(ParticleType);
|
||||
select = CheckParticleDefAndContainment(fastTrack);
|
||||
if (select) EnergyStop = PBound->GetEneToKill(ParticleType);
|
||||
}
|
||||
}
|
||||
|
||||
return select;
|
||||
return select;
|
||||
}
|
||||
|
||||
G4bool GFlashShowerModel::CheckParticleDefAndContainment(const G4FastTrack& fastTrack)
|
||||
{
|
||||
G4bool filter = false;
|
||||
G4ParticleDefinition* ParticleType = fastTrack.GetPrimaryTrack()->GetDefinition();
|
||||
|
||||
G4bool
|
||||
GFlashShowerModel::CheckParticleDefAndContainment(const G4FastTrack& fastTrack)
|
||||
{
|
||||
G4bool filter=false;
|
||||
G4ParticleDefinition * ParticleType =
|
||||
fastTrack.GetPrimaryTrack()->GetDefinition();
|
||||
|
||||
if( ParticleType == G4Electron::ElectronDefinition() ||
|
||||
ParticleType == G4Positron::PositronDefinition() )
|
||||
if (ParticleType == G4Electron::ElectronDefinition()
|
||||
|| ParticleType == G4Positron::PositronDefinition())
|
||||
{
|
||||
filter=true;
|
||||
if(FlagParticleContainment == 1)
|
||||
{
|
||||
filter=CheckContainment(fastTrack);
|
||||
filter = true;
|
||||
if (FlagParticleContainment == 1) {
|
||||
filter = CheckContainment(fastTrack);
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
return filter;
|
||||
}
|
||||
|
||||
G4bool GFlashShowerModel::CheckContainment(const G4FastTrack& fastTrack)
|
||||
{
|
||||
G4bool filter=false;
|
||||
G4bool filter = false;
|
||||
// track informations
|
||||
G4ThreeVector DirectionShower=fastTrack.GetPrimaryTrackLocalDirection();
|
||||
G4ThreeVector InitialPositionShower=fastTrack.GetPrimaryTrackLocalPosition();
|
||||
G4ThreeVector DirectionShower = fastTrack.GetPrimaryTrackLocalDirection();
|
||||
G4ThreeVector InitialPositionShower = fastTrack.GetPrimaryTrackLocalPosition();
|
||||
|
||||
G4ThreeVector OrthoShower, CrossShower;
|
||||
// Returns orthogonal vector
|
||||
G4ThreeVector OrthoShower, CrossShower;
|
||||
// Returns orthogonal vector
|
||||
OrthoShower = DirectionShower.orthogonal();
|
||||
// Shower in direction perpendicular to OrthoShower and DirectionShower
|
||||
CrossShower = DirectionShower.cross(OrthoShower);
|
||||
|
||||
G4double R = Parameterisation->GetAveR90();
|
||||
G4double Z = Parameterisation->GetAveT90();
|
||||
G4int CosPhi[4] = {1,0,-1,0};
|
||||
G4int SinPhi[4] = {0,1,0,-1};
|
||||
|
||||
|
||||
G4double R = Parameterisation->GetAveR90();
|
||||
G4double Z = Parameterisation->GetAveT90();
|
||||
G4int CosPhi[4] = {1, 0, -1, 0};
|
||||
G4int SinPhi[4] = {0, 1, 0, -1};
|
||||
|
||||
G4ThreeVector Position;
|
||||
G4int NlateralInside=0;
|
||||
G4int NlateralInside = 0;
|
||||
// pointer to solid we're in
|
||||
G4VSolid *SolidCalo = fastTrack.GetEnvelopeSolid();
|
||||
for(int i=0; i<4 ;i++)
|
||||
{
|
||||
G4VSolid* SolidCalo = fastTrack.GetEnvelopeSolid();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// polar coordinates
|
||||
Position = InitialPositionShower +
|
||||
Z*DirectionShower +
|
||||
R*CosPhi[i]*OrthoShower +
|
||||
R*SinPhi[i]*CrossShower ;
|
||||
|
||||
if(SolidCalo->Inside(Position) != kOutside)
|
||||
NlateralInside++;
|
||||
Position = InitialPositionShower + Z * DirectionShower + R * CosPhi[i] * OrthoShower
|
||||
+ R * SinPhi[i] * CrossShower;
|
||||
|
||||
if (SolidCalo->Inside(Position) != kOutside) NlateralInside++;
|
||||
}
|
||||
|
||||
|
||||
// choose to parameterise or flag when all inetc...
|
||||
if(NlateralInside==4) filter=true;
|
||||
if (NlateralInside == 4) filter = true;
|
||||
// std::cout << " points = " <<NlateralInside << std::endl;
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GFlashShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep)
|
||||
void GFlashShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep)
|
||||
{
|
||||
// parametrise electrons
|
||||
if(fastTrack.GetPrimaryTrack()->GetDefinition()
|
||||
== G4Electron::ElectronDefinition() ||
|
||||
fastTrack.GetPrimaryTrack()->GetDefinition()
|
||||
== G4Positron::PositronDefinition() )
|
||||
ElectronDoIt(fastTrack,fastStep);
|
||||
if (fastTrack.GetPrimaryTrack()->GetDefinition() == G4Electron::ElectronDefinition()
|
||||
|| fastTrack.GetPrimaryTrack()->GetDefinition() == G4Positron::PositronDefinition())
|
||||
ElectronDoIt(fastTrack, fastStep);
|
||||
}
|
||||
|
||||
void
|
||||
GFlashShowerModel::ElectronDoIt(const G4FastTrack& fastTrack,
|
||||
G4FastStep& fastStep)
|
||||
void GFlashShowerModel::ElectronDoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep)
|
||||
{
|
||||
// std::cout<<"--- ElectronDoit --- "<<std::endl;
|
||||
|
||||
|
||||
fastStep.KillPrimaryTrack();
|
||||
fastStep.ProposePrimaryTrackPathLength(0.0);
|
||||
fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->
|
||||
GetKineticEnergy());
|
||||
|
||||
fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
|
||||
|
||||
//-----------------------------
|
||||
// Get track parameters
|
||||
//-----------------------------
|
||||
//E,vect{p} and t,vec(x)
|
||||
// Get track parameters
|
||||
//-----------------------------
|
||||
// E,vect{p} and t,vec(x)
|
||||
G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
|
||||
|
||||
|
||||
// axis of the shower, in global reference frame:
|
||||
G4ThreeVector DirectionShower =
|
||||
fastTrack.GetPrimaryTrack()->GetMomentumDirection();
|
||||
G4ThreeVector DirectionShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
|
||||
G4ThreeVector OrthoShower, CrossShower;
|
||||
OrthoShower = DirectionShower.orthogonal();
|
||||
CrossShower = DirectionShower.cross(OrthoShower);
|
||||
|
||||
|
||||
//--------------------------------
|
||||
///Generate longitudinal profile
|
||||
/// Generate longitudinal profile
|
||||
//--------------------------------
|
||||
Parameterisation->GenerateLongitudinalProfile(Energy);
|
||||
// performance iteration @@@@@@@
|
||||
|
||||
///Initialisation of long. loop variables
|
||||
G4VSolid *SolidCalo = fastTrack.GetEnvelopeSolid();
|
||||
G4ThreeVector pos = fastTrack.GetPrimaryTrackLocalPosition();
|
||||
G4ThreeVector dir = fastTrack.GetPrimaryTrackLocalDirection();
|
||||
G4double Bound = SolidCalo->DistanceToOut(pos,dir);
|
||||
|
||||
G4double Dz = 0.00;
|
||||
// performance iteration @@@@@@@
|
||||
|
||||
/// Initialisation of long. loop variables
|
||||
G4VSolid* SolidCalo = fastTrack.GetEnvelopeSolid();
|
||||
G4ThreeVector pos = fastTrack.GetPrimaryTrackLocalPosition();
|
||||
G4ThreeVector dir = fastTrack.GetPrimaryTrackLocalDirection();
|
||||
G4double Bound = SolidCalo->DistanceToOut(pos, dir);
|
||||
|
||||
G4double Dz = 0.00;
|
||||
G4double ZEndStep = 0.00;
|
||||
|
||||
G4double EnergyNow = Energy;
|
||||
G4double EneIntegral = 0.00;
|
||||
G4double LastEneIntegral = 0.00;
|
||||
G4double DEne = 0.00;
|
||||
|
||||
G4double NspIntegral = 0.00;
|
||||
G4double LastNspIntegral = 0.00;
|
||||
G4double DNsp = 0.00;
|
||||
|
||||
|
||||
G4double EnergyNow = Energy;
|
||||
G4double EneIntegral = 0.00;
|
||||
G4double LastEneIntegral = 0.00;
|
||||
G4double DEne = 0.00;
|
||||
|
||||
G4double NspIntegral = 0.00;
|
||||
G4double LastNspIntegral = 0.00;
|
||||
G4double DNsp = 0.00;
|
||||
|
||||
// starting point of the shower:
|
||||
G4ThreeVector PositionShower = fastTrack.GetPrimaryTrack()->GetPosition();
|
||||
G4ThreeVector NewPositionShower = PositionShower;
|
||||
G4double StepLenght = 0.00;
|
||||
|
||||
G4ThreeVector PositionShower = fastTrack.GetPrimaryTrack()->GetPosition();
|
||||
G4ThreeVector NewPositionShower = PositionShower;
|
||||
G4double StepLenght = 0.00;
|
||||
|
||||
//--------------------------
|
||||
/// Begin Longitudinal Loop
|
||||
//-------------------------
|
||||
|
||||
do
|
||||
{
|
||||
//determine step size=min(1Xo,next boundary)
|
||||
G4double stepLength = StepInX0*Parameterisation->GetX0();
|
||||
if(Bound < stepLength)
|
||||
{
|
||||
Dz = Bound;
|
||||
|
||||
do {
|
||||
// determine step size=min(1Xo,next boundary)
|
||||
G4double stepLength = StepInX0 * Parameterisation->GetX0();
|
||||
if (Bound < stepLength) {
|
||||
Dz = Bound;
|
||||
Bound = 0.00;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dz = stepLength;
|
||||
Bound = Bound-Dz;
|
||||
else {
|
||||
Dz = stepLength;
|
||||
Bound = Bound - Dz;
|
||||
}
|
||||
ZEndStep=ZEndStep+Dz;
|
||||
|
||||
ZEndStep = ZEndStep + Dz;
|
||||
|
||||
// Determine Energy Release in Step
|
||||
if(EnergyNow > EnergyStop)
|
||||
{
|
||||
LastEneIntegral = EneIntegral;
|
||||
EneIntegral = Parameterisation->IntegrateEneLongitudinal(ZEndStep);
|
||||
DEne = std::min( EnergyNow,
|
||||
(EneIntegral-LastEneIntegral)*Energy);
|
||||
LastNspIntegral = NspIntegral;
|
||||
NspIntegral = Parameterisation->IntegrateNspLongitudinal(ZEndStep);
|
||||
DNsp = std::max(1., std::floor( (NspIntegral-LastNspIntegral)
|
||||
*Parameterisation->GetNspot() ));
|
||||
if (EnergyNow > EnergyStop) {
|
||||
LastEneIntegral = EneIntegral;
|
||||
EneIntegral = Parameterisation->IntegrateEneLongitudinal(ZEndStep);
|
||||
DEne = std::min(EnergyNow, (EneIntegral - LastEneIntegral) * Energy);
|
||||
LastNspIntegral = NspIntegral;
|
||||
NspIntegral = Parameterisation->IntegrateNspLongitudinal(ZEndStep);
|
||||
DNsp =
|
||||
std::max(1., std::floor((NspIntegral - LastNspIntegral) * Parameterisation->GetNspot()));
|
||||
}
|
||||
// end of the shower
|
||||
else
|
||||
{
|
||||
else {
|
||||
DEne = EnergyNow;
|
||||
DNsp = std::max(1., std::floor( (1.- NspIntegral)
|
||||
*Parameterisation->GetNspot() ));
|
||||
}
|
||||
EnergyNow = EnergyNow - DEne;
|
||||
|
||||
DNsp = std::max(1., std::floor((1. - NspIntegral) * Parameterisation->GetNspot()));
|
||||
}
|
||||
EnergyNow = EnergyNow - DEne;
|
||||
|
||||
// Apply sampling fluctuation - only in sampling calorimeters
|
||||
//
|
||||
GFlashSamplingShowerParameterisation* sp =
|
||||
dynamic_cast<GFlashSamplingShowerParameterisation*>(Parameterisation);
|
||||
if (sp)
|
||||
{
|
||||
G4double DEneSampling = sp->ApplySampling(DEne,Energy);
|
||||
if (sp) {
|
||||
G4double DEneSampling = sp->ApplySampling(DEne, Energy);
|
||||
DEne = DEneSampling;
|
||||
}
|
||||
|
||||
//move particle in the middle of the step
|
||||
StepLenght = StepLenght + Dz/2.00;
|
||||
NewPositionShower = NewPositionShower +
|
||||
StepLenght*DirectionShower;
|
||||
StepLenght = Dz/2.00;
|
||||
|
||||
//generate spots & hits:
|
||||
for (G4int i = 0; i < DNsp; ++i)
|
||||
{
|
||||
GFlashEnergySpot Spot;
|
||||
|
||||
//Spot energy: the same for all spots
|
||||
Spot.SetEnergy( DEne / DNsp );
|
||||
G4double PhiSpot = Parameterisation->GeneratePhi(); // phi of spot
|
||||
G4double RSpot = Parameterisation // radius of spot
|
||||
->GenerateRadius(i,Energy,ZEndStep-Dz/2.);
|
||||
// move particle in the middle of the step
|
||||
StepLenght = StepLenght + Dz / 2.00;
|
||||
NewPositionShower = NewPositionShower + StepLenght * DirectionShower;
|
||||
StepLenght = Dz / 2.00;
|
||||
|
||||
// generate spots & hits:
|
||||
for (G4int i = 0; i < DNsp; ++i) {
|
||||
GFlashEnergySpot Spot;
|
||||
|
||||
// Spot energy: the same for all spots
|
||||
Spot.SetEnergy(DEne / DNsp);
|
||||
G4double PhiSpot = Parameterisation->GeneratePhi(); // phi of spot
|
||||
G4double RSpot = Parameterisation // radius of spot
|
||||
->GenerateRadius(i, Energy, ZEndStep - Dz / 2.);
|
||||
|
||||
// check reference-> may be need to introduce rot matrix @@@
|
||||
// Position: equally spaced in z
|
||||
|
||||
G4ThreeVector SpotPosition = NewPositionShower +
|
||||
Dz/DNsp*DirectionShower*(i+1/2.-DNsp/2.) +
|
||||
RSpot*std::cos(PhiSpot)*OrthoShower +
|
||||
RSpot*std::sin(PhiSpot)*CrossShower;
|
||||
|
||||
G4ThreeVector SpotPosition =
|
||||
NewPositionShower + Dz / DNsp * DirectionShower * (i + 1 / 2. - DNsp / 2.)
|
||||
+ RSpot * std::cos(PhiSpot) * OrthoShower + RSpot * std::sin(PhiSpot) * CrossShower;
|
||||
Spot.SetPosition(SpotPosition);
|
||||
|
||||
//Generate Hits of this spot
|
||||
|
||||
// Generate Hits of this spot
|
||||
HMaker->make(&Spot, &fastTrack);
|
||||
}
|
||||
}
|
||||
while(EnergyNow > 0.0 && Bound> 0.0);
|
||||
|
||||
} while (EnergyNow > 0.0 && Bound > 0.0);
|
||||
|
||||
//---------------
|
||||
/// End Loop
|
||||
//---------------
|
||||
//---------------
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,28 +298,28 @@ GFlashShowerModel::ElectronDoIt(const G4FastTrack& fastTrack,
|
||||
void
|
||||
GFlashShowerModel::GammaDoIt(const G4FastTrack& fastTrack,
|
||||
G4FastStep& fastStep)
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
if( fastTrack.GetPrimaryTrack()->GetKineticEnergy() > EnergyStop )
|
||||
return;
|
||||
|
||||
//deposita in uno spot unico l'energia
|
||||
//con andamento exp decrescente.
|
||||
|
||||
|
||||
//deposita in uno spot unico l'energia
|
||||
//con andamento exp decrescente.
|
||||
|
||||
// Kill the particle to be parametrised
|
||||
fastStep.KillPrimaryTrack();
|
||||
fastStep.SetPrimaryTrackPathLength(0.0);
|
||||
fastStep.SetTotalEnergyDeposited(fastTrack.GetPrimaryTrack()
|
||||
->GetKineticEnergy());
|
||||
// other settings????
|
||||
feSpotList.clear();
|
||||
|
||||
feSpotList.clear();
|
||||
|
||||
//-----------------------------
|
||||
// Get track parameters
|
||||
// Get track parameters
|
||||
//-----------------------------
|
||||
|
||||
// E,vect{p} and t,vec(x)
|
||||
G4double Energy =
|
||||
G4double Energy =
|
||||
fastTrack.GetPrimaryTrack()->GetKineticEnergy();
|
||||
// axis of the shower, in global reference frame:
|
||||
G4ThreeVector DirectionShower =
|
||||
@@ -363,23 +327,23 @@ GFlashShowerModel::GammaDoIt(const G4FastTrack& fastTrack,
|
||||
// starting point of the shower:
|
||||
G4ThreeVector PositionShower =
|
||||
fastTrack.GetPrimaryTrack()->GetPosition();
|
||||
|
||||
|
||||
//G4double DEneSampling = Parameterisation->ApplySampling(Energy,Energy);
|
||||
//if(DEneSampling <= 0.00) DEneSampling=Energy;
|
||||
|
||||
//if(DEneSampling <= 0.00) DEneSampling=Energy;
|
||||
|
||||
if(Energy > 0.0)
|
||||
{
|
||||
G4double dist = Parameterisation->GenerateExponential(Energy);
|
||||
|
||||
G4double dist = Parameterisation->GenerateExponential(Energy);
|
||||
|
||||
GFlashEnergySpot Spot;
|
||||
Spot.SetEnergy( Energy );
|
||||
G4ThreeVector SpotPosition = PositionShower + dist*DirectionShower;
|
||||
G4ThreeVector SpotPosition = PositionShower + dist*DirectionShower;
|
||||
Spot.SetPosition(SpotPosition);
|
||||
|
||||
|
||||
// Record the Spot:
|
||||
feSpotList.push_back(Spot);
|
||||
|
||||
//Generate Hits of this spot
|
||||
|
||||
//Generate Hits of this spot
|
||||
HMaker->make(Spot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,143 +33,137 @@
|
||||
// Author: Joanna Weng - 9.11.2004
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "GFlashShowerModelMessenger.hh"
|
||||
#include "GFlashShowerModel.hh"
|
||||
#include "GFlashParticleBounds.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
#include "G4UIcmdWithAString.hh"
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
GFlashShowerModelMessenger::
|
||||
GFlashShowerModelMessenger(GFlashShowerModel * aModel)
|
||||
{
|
||||
#include "GFlashParticleBounds.hh"
|
||||
#include "GFlashShowerModel.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
GFlashShowerModelMessenger::GFlashShowerModelMessenger(GFlashShowerModel* aModel)
|
||||
{
|
||||
myParaDir = new G4UIdirectory("/GFlash/");
|
||||
myParaDir->SetGuidance("Parametrisation control.");
|
||||
myModel= aModel;
|
||||
|
||||
FlagCmd = new G4UIcmdWithAnInteger("/GFlash/flag",this);
|
||||
myModel = aModel;
|
||||
|
||||
FlagCmd = new G4UIcmdWithAnInteger("/GFlash/flag", this);
|
||||
FlagCmd->SetGuidance("Defines if GFlash is activated");
|
||||
FlagCmd->SetParameterName("flag",false,false);
|
||||
|
||||
ContCmd = new G4UIcmdWithAnInteger("/GFlash/containment ",this);
|
||||
FlagCmd->SetParameterName("flag", false, false);
|
||||
|
||||
ContCmd = new G4UIcmdWithAnInteger("/GFlash/containment ", this);
|
||||
ContCmd->SetGuidance("Defines if Containment is checked");
|
||||
ContCmd->SetParameterName("flag",false,false);
|
||||
|
||||
StepInX0Cmd = new G4UIcmdWithADouble("/GFlash/stepXo",this);
|
||||
ContCmd->SetParameterName("flag", false, false);
|
||||
|
||||
StepInX0Cmd = new G4UIcmdWithADouble("/GFlash/stepXo", this);
|
||||
StepInX0Cmd->SetGuidance("Defines step lenghts");
|
||||
StepInX0Cmd->SetParameterName("flag",false,false);
|
||||
|
||||
EminCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Emin",this);
|
||||
StepInX0Cmd->SetParameterName("flag", false, false);
|
||||
|
||||
EminCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Emin", this);
|
||||
EminCmd->SetGuidance("Set minimum kinetic energy to trigger parametrisation");
|
||||
EminCmd->SetParameterName("Emin",false,false);
|
||||
EminCmd->SetParameterName("Emin", false, false);
|
||||
EminCmd->SetDefaultUnit("GeV");
|
||||
EminCmd->SetUnitCategory("Energy");
|
||||
EminCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
EmaxCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Emax",this);
|
||||
EminCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
|
||||
|
||||
EmaxCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Emax", this);
|
||||
EmaxCmd->SetGuidance("Set maximum kinetic energy to trigger parametrisation");
|
||||
EmaxCmd->SetParameterName("Emax",false,false);
|
||||
EmaxCmd->SetParameterName("Emax", false, false);
|
||||
EmaxCmd->SetDefaultUnit("GeV");
|
||||
EmaxCmd->SetUnitCategory("Energy");
|
||||
EmaxCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
EkillCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Ekill",this);
|
||||
EmaxCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
|
||||
|
||||
EkillCmd = new G4UIcmdWithADoubleAndUnit("/GFlash/Ekill", this);
|
||||
EkillCmd->SetGuidance("Set maximum kinetic energy for electrons to be killed");
|
||||
EkillCmd->SetParameterName("Ekill",false,false);
|
||||
EkillCmd->SetParameterName("Ekill", false, false);
|
||||
EkillCmd->SetDefaultUnit("GeV");
|
||||
EkillCmd->SetUnitCategory("Energy");
|
||||
EkillCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
EkillCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
|
||||
}
|
||||
|
||||
|
||||
GFlashShowerModelMessenger::~GFlashShowerModelMessenger()
|
||||
{
|
||||
delete ContCmd;
|
||||
delete FlagCmd;
|
||||
delete StepInX0Cmd;
|
||||
delete StepInX0Cmd;
|
||||
delete EminCmd;
|
||||
delete EmaxCmd;
|
||||
delete EkillCmd;
|
||||
}
|
||||
|
||||
void GFlashShowerModelMessenger::SetNewValue(G4UIcommand* command, G4String newValues)
|
||||
{
|
||||
if (command == FlagCmd) {
|
||||
myModel->SetFlagParamType(FlagCmd->GetNewIntValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
if (command == ContCmd) {
|
||||
myModel->SetFlagParticleContainment(ContCmd->GetNewIntValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
if (command == StepInX0Cmd) {
|
||||
myModel->SetStepInX0(StepInX0Cmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
|
||||
void GFlashShowerModelMessenger::
|
||||
SetNewValue(G4UIcommand * command,G4String newValues)
|
||||
{
|
||||
|
||||
if( command == FlagCmd ) {
|
||||
myModel->SetFlagParamType(FlagCmd->GetNewIntValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
if( command == ContCmd ) {
|
||||
myModel->SetFlagParticleContainment(ContCmd->GetNewIntValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
if( command == StepInX0Cmd ) {
|
||||
myModel->SetStepInX0(StepInX0Cmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
|
||||
else if( command == EminCmd ) {
|
||||
else if (command == EminCmd) {
|
||||
myModel->PBound->SetMinEneToParametrise(*G4Electron::ElectronDefinition(),
|
||||
EminCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
EminCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
|
||||
else if( command == EmaxCmd ) {
|
||||
|
||||
else if (command == EmaxCmd) {
|
||||
myModel->PBound->SetMaxEneToParametrise(*G4Electron::ElectronDefinition(),
|
||||
EmaxCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
EmaxCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
|
||||
else if( command == EkillCmd ) {
|
||||
|
||||
else if (command == EkillCmd) {
|
||||
myModel->PBound->SetEneToKill(*G4Electron::ElectronDefinition(),
|
||||
EkillCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
EkillCmd->GetNewDoubleValue(newValues));
|
||||
this->GetCurrentValue(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
G4String GFlashShowerModelMessenger::GetCurrentValue(G4UIcommand * command)
|
||||
G4String GFlashShowerModelMessenger::GetCurrentValue(G4UIcommand* command)
|
||||
{
|
||||
G4String returnValue(1,'\0');
|
||||
G4String returnValue(1, '\0');
|
||||
std::ostringstream os;
|
||||
|
||||
if( command == FlagCmd ) {
|
||||
os << "/GFlash/flag " << myModel->GetFlagParamType() << '\0';
|
||||
|
||||
if (command == FlagCmd) {
|
||||
os << "/GFlash/flag " << myModel->GetFlagParamType() << '\0';
|
||||
returnValue = G4String(os.str());
|
||||
}
|
||||
|
||||
else if( command == EkillCmd ) {
|
||||
os << "/GFlash/Ekill "
|
||||
<< myModel->PBound->GetEneToKill(*G4Electron::ElectronDefinition())/GeV
|
||||
|
||||
else if (command == EkillCmd) {
|
||||
os << "/GFlash/Ekill " << myModel->PBound->GetEneToKill(*G4Electron::ElectronDefinition()) / GeV
|
||||
<< " GeV" << '\0';
|
||||
returnValue = G4String(os.str());
|
||||
}
|
||||
|
||||
else if( command == EminCmd ) {
|
||||
|
||||
else if (command == EminCmd) {
|
||||
os << "/GFlash/Emin "
|
||||
<< myModel->PBound->GetMinEneToParametrise(*G4Electron::ElectronDefinition())/GeV
|
||||
<< " GeV" << '\0';
|
||||
returnValue = G4String(os.str());
|
||||
}
|
||||
|
||||
else if( command == EmaxCmd ) {
|
||||
os << "/GFlash/Emax "
|
||||
<< myModel->PBound->GetMaxEneToParametrise(*G4Electron::ElectronDefinition())/GeV
|
||||
<< " GeV" << '\0';
|
||||
<< myModel->PBound->GetMinEneToParametrise(*G4Electron::ElectronDefinition()) / GeV << " GeV"
|
||||
<< '\0';
|
||||
returnValue = G4String(os.str());
|
||||
}
|
||||
|
||||
|
||||
else if (command == EmaxCmd) {
|
||||
os << "/GFlash/Emax "
|
||||
<< myModel->PBound->GetMaxEneToParametrise(*G4Electron::ElectronDefinition()) / GeV << " GeV"
|
||||
<< '\0';
|
||||
returnValue = G4String(os.str());
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@@ -56,30 +56,29 @@ GVFlashShowerParameterisation::~GVFlashShowerParameterisation()
|
||||
delete fGamma;
|
||||
}
|
||||
|
||||
G4double GVFlashShowerParameterisation::GetEffZ(const G4Material * mat )
|
||||
G4double GVFlashShowerParameterisation::GetEffZ(const G4Material* mat)
|
||||
{
|
||||
// Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
|
||||
// of given material
|
||||
//
|
||||
G4double z = 0.;
|
||||
G4int nofElements = (G4int)mat->GetNumberOfElements();
|
||||
if (nofElements > 1)
|
||||
{
|
||||
for (G4int i=0; i<nofElements; ++i) {
|
||||
if (nofElements > 1) {
|
||||
for (G4int i = 0; i < nofElements; ++i) {
|
||||
G4double zOfElement = mat->GetElement(i)->GetZ();
|
||||
G4double massFraction = mat->GetFractionVector()[i];
|
||||
// cout << mat->GetElement(i)->GetName()
|
||||
// <<" Z= "<<zOfElement << " , Fraction= "<<massFraction <<endl;
|
||||
z += zOfElement*massFraction;
|
||||
z += zOfElement * massFraction;
|
||||
}
|
||||
}
|
||||
else {
|
||||
z = mat->GetZ();
|
||||
}
|
||||
else {
|
||||
z = mat->GetZ();
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
G4double GVFlashShowerParameterisation::GetEffA (const G4Material * mat )
|
||||
G4double GVFlashShowerParameterisation::GetEffA(const G4Material* mat)
|
||||
{
|
||||
// Returns A or effective A=sum(pi*Ai) (if compound/mixture)
|
||||
// of given material
|
||||
@@ -87,29 +86,29 @@ G4double GVFlashShowerParameterisation::GetEffA (const G4Material * mat )
|
||||
G4double a = 0.;
|
||||
G4int nofElements = (G4int)mat->GetNumberOfElements();
|
||||
if (nofElements > 1) {
|
||||
for (G4int i=0; i<nofElements; ++i) {
|
||||
G4double aOfElement = mat->GetElement(i)->GetA()/(g/mole);
|
||||
G4double massFraction = mat->GetFractionVector()[i];
|
||||
a += aOfElement*massFraction;
|
||||
for (G4int i = 0; i < nofElements; ++i) {
|
||||
G4double aOfElement = mat->GetElement(i)->GetA() / (g / mole);
|
||||
G4double massFraction = mat->GetFractionVector()[i];
|
||||
a += aOfElement * massFraction;
|
||||
}
|
||||
}
|
||||
else {
|
||||
a = mat->GetA()/(g/mole);
|
||||
else {
|
||||
a = mat->GetA() / (g / mole);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
void GVFlashShowerParameterisation::PrintMaterial(const G4Material * mat)
|
||||
void GVFlashShowerParameterisation::PrintMaterial(const G4Material* mat)
|
||||
{
|
||||
G4cout<<"/********************************************/ " << G4endl;
|
||||
G4cout<<" - GVFlashShowerParameterisation::Material - " << G4endl;
|
||||
G4cout<<" Material : " << mat->GetName() << G4endl;
|
||||
G4cout<<" Z = " << Z << G4endl;
|
||||
G4cout<<" A = " << A << G4endl;
|
||||
G4cout<<" X0 = " << X0/cm << " cm" << G4endl;
|
||||
G4cout<<" Rm = " << Rm/cm << " cm" << G4endl;
|
||||
G4cout<<" Ec = " << Ec/MeV << " MeV"<< G4endl;
|
||||
G4cout<<"/********************************************/ " << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
G4cout << " - GVFlashShowerParameterisation::Material - " << G4endl;
|
||||
G4cout << " Material : " << mat->GetName() << G4endl;
|
||||
G4cout << " Z = " << Z << G4endl;
|
||||
G4cout << " A = " << A << G4endl;
|
||||
G4cout << " X0 = " << X0 / cm << " cm" << G4endl;
|
||||
G4cout << " Rm = " << Rm / cm << " cm" << G4endl;
|
||||
G4cout << " Ec = " << Ec / MeV << " MeV" << G4endl;
|
||||
G4cout << "/********************************************/ " << G4endl;
|
||||
}
|
||||
|
||||
G4double GVFlashShowerParameterisation::GeneratePhi()
|
||||
@@ -118,7 +117,7 @@ G4double GVFlashShowerParameterisation::GeneratePhi()
|
||||
return Phi;
|
||||
}
|
||||
|
||||
G4double GVFlashShowerParameterisation::gam(G4double x, G4double a) const
|
||||
G4double GVFlashShowerParameterisation::gam(G4double x, G4double a) const
|
||||
{
|
||||
return fGamma->Gamma(a, x);
|
||||
return fGamma->Gamma(a, x);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ double MyGamma::Gamma(double z)
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
double MyGamma::Gamma(double a,double x)
|
||||
double MyGamma::Gamma(double a, double x)
|
||||
{
|
||||
// Computation of the incomplete gamma function P(a,x)
|
||||
//
|
||||
@@ -55,15 +55,17 @@ double MyGamma::Gamma(double a,double x)
|
||||
// Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
|
||||
//
|
||||
//--- Nve 14-nov-1998 UU-SAP Utrecht
|
||||
|
||||
|
||||
if (a <= 0 || x <= 0) return 0;
|
||||
|
||||
if (x < (a+1)) return GamSer(a,x);
|
||||
else return GamCf(a,x);
|
||||
|
||||
if (x < (a + 1))
|
||||
return GamSer(a, x);
|
||||
else
|
||||
return GamCf(a, x);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
double MyGamma::GamCf(double a,double x)
|
||||
double MyGamma::GamCf(double a, double x)
|
||||
{
|
||||
// Computation of the incomplete gamma function P(a,x)
|
||||
// via its continued fraction representation.
|
||||
@@ -72,38 +74,38 @@ double MyGamma::GamCf(double a,double x)
|
||||
// Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
|
||||
//
|
||||
//--- Nve 14-nov-1998 UU-SAP Utrecht
|
||||
|
||||
int itmax = 100; // Maximum number of iterations
|
||||
double eps = 3.e-7; // Relative accuracy
|
||||
double fpmin = 1.e-30; // Smallest double value allowed here
|
||||
|
||||
|
||||
int itmax = 100; // Maximum number of iterations
|
||||
double eps = 3.e-7; // Relative accuracy
|
||||
double fpmin = 1.e-30; // Smallest double value allowed here
|
||||
|
||||
if (a <= 0 || x <= 0) return 0;
|
||||
|
||||
|
||||
double gln = LnGamma(a);
|
||||
double b = x+1-a;
|
||||
double c = 1/fpmin;
|
||||
double d = 1/b;
|
||||
double h = d;
|
||||
double an,del;
|
||||
for (int i=1; i<=itmax; i++) {
|
||||
an = double(-i)*(double(i)-a);
|
||||
double b = x + 1 - a;
|
||||
double c = 1 / fpmin;
|
||||
double d = 1 / b;
|
||||
double h = d;
|
||||
double an, del;
|
||||
for (int i = 1; i <= itmax; i++) {
|
||||
an = double(-i) * (double(i) - a);
|
||||
b += 2;
|
||||
d = an*d+b;
|
||||
d = an * d + b;
|
||||
if (Abs(d) < fpmin) d = fpmin;
|
||||
c = b+an/c;
|
||||
c = b + an / c;
|
||||
if (Abs(c) < fpmin) c = fpmin;
|
||||
d = 1/d;
|
||||
del = d*c;
|
||||
h = h*del;
|
||||
if (Abs(del-1) < eps) break;
|
||||
//if (i==itmax) cout << "*GamCf(a,x)* a too large or itmax too small" << endl;
|
||||
d = 1 / d;
|
||||
del = d * c;
|
||||
h = h * del;
|
||||
if (Abs(del - 1) < eps) break;
|
||||
// if (i==itmax) cout << "*GamCf(a,x)* a too large or itmax too small" << endl;
|
||||
}
|
||||
double v = Exp(-x+a*Log(x)-gln)*h;
|
||||
return (1-v);
|
||||
double v = Exp(-x + a * Log(x) - gln) * h;
|
||||
return (1 - v);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
double MyGamma::GamSer(double a,double x)
|
||||
double MyGamma::GamSer(double a, double x)
|
||||
{
|
||||
// Computation of the incomplete gamma function P(a,x)
|
||||
// via its series representation.
|
||||
@@ -112,28 +114,27 @@ double MyGamma::GamSer(double a,double x)
|
||||
// Numerical Recipes 2nd ed. on p. 210-212 (W.H.Press et al.).
|
||||
//
|
||||
//--- Nve 14-nov-1998 UU-SAP Utrecht
|
||||
|
||||
int itmax = 100; // Maximum number of iterations
|
||||
double eps = 3.e-7; // Relative accuracy
|
||||
|
||||
|
||||
int itmax = 100; // Maximum number of iterations
|
||||
double eps = 3.e-7; // Relative accuracy
|
||||
|
||||
if (a <= 0 || x <= 0) return 0;
|
||||
|
||||
|
||||
double gln = LnGamma(a);
|
||||
double ap = a;
|
||||
double sum = 1/a;
|
||||
double ap = a;
|
||||
double sum = 1 / a;
|
||||
double del = sum;
|
||||
for (int n=1; n<=itmax; n++) {
|
||||
ap += 1;
|
||||
del = del*x/ap;
|
||||
for (int n = 1; n <= itmax; n++) {
|
||||
ap += 1;
|
||||
del = del * x / ap;
|
||||
sum += del;
|
||||
if (MyGamma::Abs(del) < Abs(sum*eps)) break;
|
||||
//if (n==itmax) cout << "*GamSer(a,x)* a too large or itmax too small" << endl;
|
||||
if (MyGamma::Abs(del) < Abs(sum * eps)) break;
|
||||
// if (n==itmax) cout << "*GamSer(a,x)* a too large or itmax too small" << endl;
|
||||
}
|
||||
double v = sum*Exp(-x+a*Log(x)-gln);
|
||||
double v = sum * Exp(-x + a * Log(x) - gln);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
double MyGamma::LnGamma(double z)
|
||||
{
|
||||
if (z <= 0)
|
||||
|
||||
Reference in New Issue
Block a user