Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
@@ -0,0 +1,75 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05CalorimeterHit.cc,v 2.2 1998/07/13 16:34:05 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05CalorimeterHit.hh"
#include "G4VVisManager.hh"
#include "G4Colour.hh"
#include "G4VisAttributes.hh"
#include "G4LogicalVolume.hh"
#include "G4ios.hh"
G4Allocator<ExN05CalorimeterHit> ExN05CalorimeterHitAllocator;
ExN05CalorimeterHit::ExN05CalorimeterHit()
{pLogV=NULL;}
ExN05CalorimeterHit::ExN05CalorimeterHit(G4LogicalVolume* logVol)
:pLogV(logVol)
{;}
ExN05CalorimeterHit::~ExN05CalorimeterHit()
{;}
ExN05CalorimeterHit::ExN05CalorimeterHit(const ExN05CalorimeterHit &right)
{
edep = right.edep;
pos = right.pos;
rot = right.rot;
pLogV = right.pLogV;
}
const ExN05CalorimeterHit& ExN05CalorimeterHit::operator=(const ExN05CalorimeterHit &right)
{
edep = right.edep;
pos = right.pos;
rot = right.rot;
pLogV = right.pLogV;
return *this;
}
int ExN05CalorimeterHit::operator==(const ExN05CalorimeterHit &right) const
{
return 0;
}
void ExN05CalorimeterHit::Draw()
{
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if(pVVisManager)
{
G4Transform3D trans(rot,pos);
G4VisAttributes attribs;
const G4VisAttributes* pVA = pLogV->GetVisAttributes();
if(pVA) attribs = *pVA;
G4Colour colour(1.,0.,0.);
attribs.SetColour(colour);
attribs.SetForceWireframe(false);
attribs.SetForceSolid(true);
pVVisManager->Draw(*pLogV,attribs,trans);
}
}
void ExN05CalorimeterHit::Print()
{
}
@@ -0,0 +1,98 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05CalorimeterSD.cc,v 2.6 1998/12/11 19:14:06 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05CalorimeterSD.hh"
#include "ExN05CalorimeterHit.hh"
#include "G4VPhysicalVolume.hh"
#include "G4LogicalVolume.hh"
#include "G4Track.hh"
#include "G4ParticleDefinition.hh"
#include "G4SDManager.hh"
#include "G4ios.hh"
ExN05CalorimeterSD::ExN05CalorimeterSD(G4String name, G4int nCells, G4String colName)
:G4VSensitiveDetector(name),numberOfCells(nCells),HCID(-1)
{
G4String HCname;
collectionName.insert(HCname=colName);
CellID = new int[numberOfCells];
}
ExN05CalorimeterSD::~ExN05CalorimeterSD()
{
delete [] CellID;
}
void ExN05CalorimeterSD::Initialize(G4HCofThisEvent*HCE)
{
CalCollection = new ExN05CalorimeterHitsCollection
(SensitiveDetectorName,collectionName[0]);
for(int j=0;j<numberOfCells;j++)
{
CellID[j] = -1;
}
}
G4bool ExN05CalorimeterSD::ProcessHits(G4Step*aStep,G4TouchableHistory*ROhist)
{
G4double edep = aStep->GetTotalEnergyDeposit();
if(edep<=0.) return false;
const G4VPhysicalVolume* physVol
= aStep->GetPreStepPoint()->GetPhysicalVolume();
int copyID = physVol->GetCopyNo();
if(CellID[copyID]==-1)
{
ExN05CalorimeterHit* calHit = new ExN05CalorimeterHit(physVol->GetLogicalVolume());
G4RotationMatrix rotM;
if(physVol->GetObjectRotation()) rotM = *(physVol->GetObjectRotation());
calHit->SetEdep( edep );
calHit->SetPos( physVol->GetTranslation() );
calHit->SetRot( rotM );
int icell = CalCollection->insert( calHit );
CellID[copyID] = icell - 1;
if(verboseLevel>0)
{ G4cout << " New Calorimeter Hit on CellID " << copyID << endl; }
}
else
{
(*CalCollection)[CellID[copyID]]->AddEdep( edep );
if(verboseLevel>0)
{ G4cout << " Energy added to CellID " << copyID << endl; }
}
return true;
}
void ExN05CalorimeterSD::EndOfEvent(G4HCofThisEvent*HCE)
{
if(HCID<0)
{ HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); }
HCE->AddHitsCollection( HCID, CalCollection );
}
void ExN05CalorimeterSD::clear()
{
}
void ExN05CalorimeterSD::DrawAll()
{
}
void ExN05CalorimeterSD::PrintAll()
{
}
@@ -0,0 +1,357 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05DetectorConstruction.cc,v 2.8 1998/12/14 16:58:12 sadilov Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05DetectorConstruction.hh"
#include "ExN05CalorimeterSD.hh"
#include "ExN05DetectorMessenger.hh"
#include "ExN05EMShowerModel.hh"
#include "ExN05PionShowerModel.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4Element.hh"
#include "G4ElementTable.hh"
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4LogicalVolume.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "G4SDManager.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4UserLimits.hh"
#include "G4FastSimulationManager.hh"
ExN05DetectorConstruction::ExN05DetectorConstruction()
{
theUserLimitsForCrystal = NULL;
fUseUserLimits = false;
theMaxTimeCutsInCrystal = 1000.0 * ns;
theMinEkineCutsInCrystal = 1.0 * MeV;
theMinRangeCutsInCrystal = 1.0 * mm;
theMessenger = new ExN05DetectorMessenger(this);
}
ExN05DetectorConstruction::~ExN05DetectorConstruction()
{
if (theUserLimitsForCrystal != NULL) delete theUserLimitsForCrystal;
delete theMessenger;
}
G4VPhysicalVolume* ExN05DetectorConstruction::Construct()
{
G4cout << "\nExN05DetectorConstruction....\n" << endl;
//--------- Material definition ---------
G4double a, iz, z, density;
G4String name, symbol;
G4int nel;
a = 14.01*g/mole;
G4Element* elN = new G4Element(name="Nitrogen", symbol="N", iz=7., a);
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxigen", symbol="O", iz=8., a);
a = 126.9*g/mole;
G4Element* elI = new G4Element(name="Iodine", symbol="I", iz=53., a);
a = 132.9*g/mole;
G4Element* elCs= new G4Element(name="Cesium", symbol="Cs", iz=55., a);
density = 4.51*g/cm3;
G4Material* CsI = new G4Material(name="CsI", density, nel = 2);
CsI->AddElement(elI, .5);
CsI->AddElement(elCs,.5);
a = 4.0*g/mole;
density = 0.1786e-03*g/cm3;
G4Material* He = new G4Material(name="He", z=2., a, density);
a = 26.98*g/mole;
density = 2.7*g/cm3;
G4Material* Al = new G4Material(name="Aluminium", z=13., a, density);
a = 207.19*g/mole;
density = 11.35*g/cm3;
G4Material* Pb = new G4Material(name="Lead", z=82., a, density);
a = 55.85*g/mole;
density = 7.87*g/cm3;
G4Material* Fe = new G4Material(name="Fer", z=26., a, density);
density = 1.29e-03*g/cm3;
G4Material* Air = new G4Material(name="Air", density, nel=2);
Air->AddElement(elN, .7);
Air->AddElement(elO, .3);
//--------- G4VSolid, G4LogicalVolume, G4VPhysicalVolume ---------
//--------------
// World:
//--------------
G4Box *WorldBox= new G4Box("WorldBox",400*cm, 400*cm, 400*cm);
G4LogicalVolume *WorldLog=new G4LogicalVolume(WorldBox,Air,
"WorldLogical", 0, 0, 0);
G4PVPlacement *WorldPhys=new G4PVPlacement(0,G4ThreeVector(),
"WorldPhysical",
WorldLog,
0,false,0);
// Size of detectors:
G4double detectSize = 125*cm;
//-----------------------------
// "Drift Chamber":
// Not used in parameterisation.
//-----------------------------
// -- Logical volume:
G4Box *driftChamberBox
= new G4Box("DriftChamberSolid", detectSize, detectSize, 40*cm);
G4LogicalVolume *driftChamberLog = new G4LogicalVolume(driftChamberBox,He,
"DriftChamberLogical", 0, 0, 0);
// -- Placement:
G4PVPlacement *driftChamberPhys = new G4PVPlacement(0,G4ThreeVector(0., 0., 50*cm),
"DriftChamberPhysical",
driftChamberLog,
WorldPhys,false,0);
//--------------------------
// "Calorimeter": used in
// parameterisation below
//--------------------------
// -- Logical volume:
G4Box *calorimeterBox
= new G4Box("CalorimeterSolid", detectSize, detectSize, 20*cm);
G4LogicalVolume *calorimeterLog = new G4LogicalVolume(calorimeterBox,Air,
"CalorimeterLogical", 0, 0, 0);
// -- Placement:
G4PVPlacement *calorimeterPhys = new G4PVPlacement(0,G4ThreeVector(0., 0., 120*cm),
"CalorimeterPhysical",
calorimeterLog,
WorldPhys,false,0);
//--------------------------------------
// The calorimeter is filled with
// crystals:
//--------------------------------------
// -- Logical volume:
G4double CrystalX = 2.5*cm;
G4double CrystalY = CrystalX;
G4double CrystalZ = 20*cm;
G4Box *CrystalSolid = new G4Box("CrystalSolid", CrystalX, CrystalY, CrystalZ);
theCrystalLog = new G4LogicalVolume(CrystalSolid,CsI,
"CrystalLogical", 0, 0, 0);
// create UserLimits
if (theUserLimitsForCrystal != NULL) delete theUserLimitsForCrystal;
theUserLimitsForCrystal = new G4UserLimits( DBL_MAX, //step max
DBL_MAX, // track max
theMaxTimeCutsInCrystal,
theMinEkineCutsInCrystal,
theMinRangeCutsInCrystal );
// attach UserLimits
if (fUseUserLimits) {
theCrystalLog->SetUserLimits(theUserLimitsForCrystal);
}
G4String tName1("Crystal"); // Allow all target physicals to share
// same name (delayed copy)
// -- and placements inside the calorimeter:
G4PVPlacement *crystalPhys;
G4int copyNo=0;
G4double xTlate, yTlate;
G4int nX = 48;
G4int nY = 48;
for (G4int j = 0; j < nY; j++)
{
yTlate = -detectSize + 3*CrystalY + j*2*CrystalY;
for (G4int i = 0; i < nX; i++)
{
xTlate = -detectSize + 3*CrystalX + i*2*CrystalX;
crystalPhys
= new G4PVPlacement(0,G4ThreeVector(xTlate,yTlate,0*cm),
tName1,
theCrystalLog,
calorimeterPhys,false,copyNo++);
}
}
//--------------------------
// "Hadron Calorimeter": used
// in parameterisation with
// a ghost volume
//--------------------------
// -- Logical volume:
G4Box *hadCaloBox
= new G4Box("HadCaloSolid", detectSize, detectSize, 50*cm);
G4LogicalVolume *hadCaloLog = new G4LogicalVolume(hadCaloBox,Air,
"HadCaloLogical", 0, 0, 0);
// -- Placement:
G4PVPlacement *hadCaloPhys = new G4PVPlacement(0,G4ThreeVector(0., 0., 200*cm),
"HadCaloPhysical",
hadCaloLog,
WorldPhys,false,0);
//--------------------------------------
// The calorimeter is filled with
// towers:
//--------------------------------------
// -- Logical volume:
G4double TowerX = 5*cm;
G4double TowerY = TowerX;
G4double TowerZ = 45*cm;
G4Box *TowerSolid = new G4Box("TowerSolid", TowerX, TowerY, TowerZ);
theTowerLog = new G4LogicalVolume(TowerSolid,Fe,
"TowerLogical", 0, 0, 0);
G4String tName2("Tower");
// -- and placements inside the calorimeter:
G4PVPlacement *towerPhys;
copyNo=0;
G4int nXhad = 23;
G4int nYhad = 23;
for (G4int jj = 0; jj < nYhad; jj++)
{
yTlate = -detectSize + 3*TowerY + jj*2*TowerY;
for (G4int i = 0; i < nXhad; i++)
{
xTlate = -detectSize + 3*TowerX + i*2*TowerX;
towerPhys
= new G4PVPlacement(0,G4ThreeVector(xTlate,yTlate,0*cm),
tName2,
theTowerLog,
hadCaloPhys,false,copyNo++);
}
}
//------------------------------------------------------------
//
//
//--------------- Ghost Volumes ------------------------------------
// Ghost volumes will be placed in an automatic copy of the world volume.
// The placement of the ghost logical volume are specified by the
// G4FastSimulationManager object attached to it.
// Those placement are given compared to the world.
// -- Solid:
G4Box *ghostBox
= new G4Box("GhostBox", detectSize+5*cm, detectSize+5*cm, 80*cm);
// -- Logical volume:
G4LogicalVolume* ghostLogical
= new G4LogicalVolume(ghostBox,Air,
"GhostLogical",
0, 0, 0);
// G4FastSimulationManager doesn't exist yet: we set it
// (not needed if we set a G4VFastSimulationModel which
// takes care of creating one if needed)
new G4FastSimulationManager(ghostLogical);
ghostLogical->GetFastSimulationManager()->
AddGhostPlacement(0,G4ThreeVector(0., 0., 175*cm));
//--------- Sensitive detector -------------------------------------
G4SDManager* SDman = G4SDManager::GetSDMpointer();
G4String calorimeterSDname = "ExN05/Calorimeter";
ExN05CalorimeterSD* CalorimeterSD = new ExN05CalorimeterSD( calorimeterSDname, nX*nY, "CalCollection" );
SDman->AddNewDetector( CalorimeterSD );
theCrystalLog->SetSensitiveDetector(CalorimeterSD);
G4String hadCalorimeterSDname = "ExN05/HadronCalorimeter";
ExN05CalorimeterSD* HadCalorimeterSD = new ExN05CalorimeterSD( hadCalorimeterSDname, nXhad*nYhad, "HadCollection" );
SDman->AddNewDetector( HadCalorimeterSD );
theTowerLog->SetSensitiveDetector(HadCalorimeterSD);
//------------------ Parameterisation ------------------------------
// builds a model and sets it to the envelope of the calorimeter:
ExN05EMShowerModel* emShowerModel =
new ExN05EMShowerModel("emShowerModel",calorimeterLog);
// and a model attached to the ghost:
ExN05PionShowerModel* ghostPionShowerModel =
new ExN05PionShowerModel("ghostPionShowerModel",ghostLogical);
//--------- Visualization attributes -------------------------------
WorldLog->SetVisAttributes(G4VisAttributes::Invisible);
G4VisAttributes * driftchamberTubeVisAtt
= new G4VisAttributes(G4Colour(0.0,1.0,0.0));
driftchamberTubeVisAtt->SetForceWireframe(true);
driftChamberLog->SetVisAttributes(driftchamberTubeVisAtt);
G4VisAttributes * calorimeterBoxVisAtt
= new G4VisAttributes(G4Colour(0.0,0.0,1.0));
calorimeterBoxVisAtt->SetForceWireframe(true);
calorimeterLog->SetVisAttributes(calorimeterBoxVisAtt);
G4VisAttributes * crystalVisAtt
= new G4VisAttributes(G4Colour(1.0,0.0,0.0));
crystalVisAtt->SetForceWireframe(true);
theCrystalLog->SetVisAttributes(crystalVisAtt);
G4VisAttributes * hadCaloBoxVisAtt
= new G4VisAttributes(G4Colour(1.0,0.0,1.0));
hadCaloBoxVisAtt->SetForceWireframe(true);
hadCaloLog->SetVisAttributes(hadCaloBoxVisAtt);
G4VisAttributes * towerVisAtt
= new G4VisAttributes(G4Colour(0.5,0.0,1.0));
towerVisAtt->SetForceWireframe(true);
theTowerLog->SetVisAttributes(towerVisAtt);
G4VisAttributes * ghostVisAtt
= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
ghostVisAtt->SetForceWireframe(true);
ghostLogical->SetVisAttributes(ghostVisAtt);
//------------------------------------------------------------------
//-----------------------
// Returns the pointer to
// the physical world:
//-----------------------
return WorldPhys;
}
void ExN05DetectorConstruction::SetMaxTimeInCrystal(G4double value)
{
theMaxTimeCutsInCrystal = value;
if (theUserLimitsForCrystal != NULL) {
theUserLimitsForCrystal->SetUserMaxTime(value);
}
}
void ExN05DetectorConstruction::SetMinEkineInCrystal(G4double value)
{
theMinEkineCutsInCrystal = value;
if (theUserLimitsForCrystal != NULL) {
theUserLimitsForCrystal->SetUserMinEkine(value);
}
}
void ExN05DetectorConstruction::SetMinRangeInCrystal(G4double value)
{
theMinRangeCutsInCrystal = value;
if (theUserLimitsForCrystal != NULL) {
theUserLimitsForCrystal->SetUserMinRange(value);
}
}
void ExN05DetectorConstruction::UseUserLimits(G4bool isUse)
{
fUseUserLimits = isUse;
if ( fUseUserLimits && (theUserLimitsForCrystal!= NULL)) {
theCrystalLog->SetUserLimits(theUserLimitsForCrystal);
}
}
@@ -0,0 +1,114 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05DetectorMessenger.cc,v 2.1 1998/08/14 08:21:21 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
#include "ExN05DetectorMessenger.hh"
#include "ExN05DetectorConstruction.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "globals.hh"
#include <iomanip.h>
#ifdef WIN32
# include <Strstrea.h>
#else
# include <strstream.h>
#endif
ExN05DetectorMessenger::ExN05DetectorMessenger(ExN05DetectorConstruction * myDet) : myDetector(myDet)
{
mydetDir = new G4UIdirectory("/exN05/detector/");
mydetDir->SetGuidance("ExN05 detector control.");
SwitchCmd = new G4UIcmdWithAString("/exN05/detector/switchUserLimits",this);
SwitchCmd->SetGuidance("Switch On/Off UserLimits for crystals");
SwitchCmd->SetGuidance(" Choice : on / off ");
SwitchCmd->SetParameterName("choice",true);
SwitchCmd->SetDefaultValue("on");
SwitchCmd->SetCandidates("on ON off OFF");
SwitchCmd->AvailableForStates(PreInit,Idle);
TmaxCmd = new G4UIcmdWithADoubleAndUnit("/exN05/detector/maxTime",this);
TmaxCmd->SetGuidance("Set maximum time in crystal");
TmaxCmd->SetParameterName("Tmax",false,false);
TmaxCmd->SetDefaultUnit("ns");
TmaxCmd->SetUnitCategory("Time");
TmaxCmd->AvailableForStates(PreInit,Idle);
EminCmd = new G4UIcmdWithADoubleAndUnit("/exN05/detector/minEkine",this);
EminCmd->SetGuidance("Set minimum kinetic energy in crystal");
EminCmd->SetParameterName("Emin",false,false);
EminCmd->SetDefaultUnit("MeV");
EminCmd->SetUnitCategory("Energy");
EminCmd->AvailableForStates(PreInit,Idle);
RminCmd = new G4UIcmdWithADoubleAndUnit("/exN05/detector/minRange",this);
RminCmd->SetGuidance("Set minimum range in crystal");
RminCmd->SetParameterName("Rmin",false,false);
RminCmd->SetDefaultUnit("mm");
RminCmd->SetUnitCategory("Length");
RminCmd->AvailableForStates(PreInit,Idle);
}
ExN05DetectorMessenger::~ExN05DetectorMessenger()
{
delete SwitchCmd;
delete TmaxCmd;
delete RminCmd;
delete EminCmd;
}
void ExN05DetectorMessenger::SetNewValue(G4UIcommand * command,G4String newValues)
{
if( command == SwitchCmd ) {
if ( (newValues == "off") || (newValues == "OFF") ){
myDetector->UseUserLimits(false);
} else {
myDetector->UseUserLimits(true);
}
} else if( command == TmaxCmd ) {
myDetector->SetMaxTimeInCrystal(TmaxCmd->GetNewDoubleValue(newValues));
} else if( command == EminCmd ) {
myDetector->SetMinEkineInCrystal(EminCmd->GetNewDoubleValue(newValues));
} else if( command == RminCmd ) {
myDetector->SetMinRangeInCrystal(RminCmd->GetNewDoubleValue(newValues));
}
}
G4String ExN05DetectorMessenger::GetCurrentValue(G4UIcommand * command)
{
G4String returnValue('\0');
char line[255];
ostrstream os(line,255);
if( command == SwitchCmd ) {
if ( myDetector->IsUseUserLimits() )returnValue = "on";
else returnValue = "off";
} else if( command == TmaxCmd ) {
os << myDetector->GetMaxTimeInCrystal()/ns << " ns" << '\0';
returnValue = G4String(line);
} else if( command == EminCmd ) {
os << myDetector->GetMinEkineInCrystal()/MeV << " MeV" << '\0';
returnValue = G4String(line);
} else if( command == RminCmd ) {
os << myDetector->GetMinRangeInCrystal()/mm << " mm" << '\0';
returnValue = G4String(line);
}
return returnValue;
}
@@ -0,0 +1,237 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05EMShowerModel.cc,v 2.4 1998/12/10 04:07:39 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05EMShowerModel.hh"
#include "ExN05EnergySpot.hh"
#include "RandomGamma.hh"
#include "Randomize.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
ExN05EMShowerModel::ExN05EMShowerModel(G4String modelName, G4LogicalVolume* envelope)
: G4VFastSimulationModel(modelName, envelope)
{
fFakeStep = new G4Step();
fFakePreStepPoint = fFakeStep->GetPreStepPoint();
fFakePostStepPoint = fFakeStep->GetPostStepPoint();
fpTouchable = new G4TouchableHistory();
fpNavigator = new G4Navigator();
fNaviSetup = false;
}
ExN05EMShowerModel::ExN05EMShowerModel(G4String modelName)
: G4VFastSimulationModel(modelName)
{
fFakeStep = new G4Step();
fFakePreStepPoint = fFakeStep->GetPreStepPoint();
fFakePostStepPoint = fFakeStep->GetPostStepPoint();
fpTouchable = new G4TouchableHistory();
fpNavigator = new G4Navigator();
fNaviSetup = false;
}
ExN05EMShowerModel::~ExN05EMShowerModel()
{
delete fFakeStep;
delete fpTouchable;
delete fpNavigator;
}
G4bool ExN05EMShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
{
return
&particleType == G4Electron::ElectronDefinition() ||
&particleType == G4Positron::PositronDefinition() ||
&particleType == G4Gamma::GammaDefinition();
}
G4bool ExN05EMShowerModel::ModelTrigger(const G4FastTrack& fastTrack)
{
// Applies the parameterisation above 100 MeV:
return fastTrack.GetPrimaryTrack()->GetKineticEnergy() > 100*MeV;
}
void ExN05EMShowerModel::DoIt(const G4FastTrack& fastTrack,
G4FastStep& fastStep)
{
// Kill the parawmeterised particle:
fastStep.KillPrimaryTrack();
fastStep.SetPrimaryTrackPathLength(0.0);
fastStep.SetTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
// split into "energy spots" energy according to the shower shape:
Explode(fastTrack);
// and put those energy spots into the crystals:
BuildDetectorResponse();
}
void ExN05EMShowerModel::Explode(const G4FastTrack& fastTrack)
{
//-----------------------------------------------------
//
//-----------------------------------------------------
// Reduced quantities:
// -- critical energy in CsI:
G4double Ec = 800*MeV/(54. + 1.2); // 54 = mean Z of CsI
G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
G4double y = Energy/Ec;
// compute value of parameter "a" of longitudinal profile, b assumed = 0.5
G4double a, tmax, b(0.5), C;
if (fastTrack.GetPrimaryTrack()->GetDefinition() == G4Gamma::GammaDefinition()) C = 0.5;
else C = -0.5;
tmax = 1.0 * (log(y) + C);
a = 1.0 + b*tmax;
// t : reduced quantity = z/X0:
G4double t, bt;
G4Material* CsI = G4Material::GetMaterial("CsI");
G4double X0 = CsI->GetRadlen();
// Moliere radius:
G4double Es = 21*MeV;
G4double Rm = X0*Es/Ec;
// axis of the shower, in global reference frame:
G4ThreeVector xShower, yShower, zShower;
zShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
xShower = zShower.orthogonal();
yShower = zShower.cross(xShower);
// starting point of the shower:
G4ThreeVector sShower = fastTrack.GetPrimaryTrack()->GetPosition();
// We shoot 100 spots of energy:
G4int nSpots = 100;
G4double deposit = Energy/double(nSpots);
ExN05EnergySpot eSpot;
eSpot.SetEnergy(deposit);
G4ThreeVector ePoint;
G4double z, r, phi;
feSpotList.clear();
for (int i = 0; i < nSpots; i++)
{
// Longitudinal profile:
// -- shoot z according to Gamma distribution:
bt = RandomGamma(a);
t = bt/b;
z = t*X0;
// transverse profile:
// we set 90% of energy in one Rm,
// the rest between 1 and 3.5 Rm:
G4double xr = G4UniformRand();
if (xr < 0.9) r = xr/0.9*Rm;
else r = ((xr - 0.9)/0.1*2.5 + 1.0)*Rm;
phi = G4UniformRand()*twopi;
// build the position:
ePoint = sShower +
z*zShower +
r*cos(phi)*xShower + r*sin(phi)*yShower;
// and the energy spot:
eSpot.SetPosition(ePoint);
// Records the eSpot:
feSpotList.insert(eSpot);
}
}
void ExN05EMShowerModel::BuildDetectorResponse()
{
// Does the assignation of the energy spots to the sensitive volumes:
for (int i = 0; i < feSpotList.entries(); i++)
{
// Draw the energy spot:
feSpotList[i].Draw();
// feSpotList[i].Print();
// "converts" the energy spot into the fake
// G4Step to pass to sensitive detector:
AssignSpotAndCallHit(feSpotList[i]);
}
}
void ExN05EMShowerModel::AssignSpotAndCallHit(const ExN05EnergySpot &eSpot)
{
//
// "converts" the energy spot into the fake
// G4Step to pass to sensitive detector:
//
FillFakeStep(eSpot);
//
// call sensitive part: taken/adapted from the stepping:
// Send G4Step information to Hit/Dig if the volume is sensitive
//
G4VPhysicalVolume* pCurrentVolume =
fFakeStep->GetPreStepPoint()->GetPhysicalVolume();
G4VSensitiveDetector* pSensitive;
if( pCurrentVolume != 0 )
{
pSensitive = pCurrentVolume->GetLogicalVolume()->
GetSensitiveDetector();
if( pSensitive != 0 )
{
pSensitive->Hit(fFakeStep);
}
}
}
void ExN05EMShowerModel::FillFakeStep(const ExN05EnergySpot &eSpot)
{
//-----------------------------------------------------------
// find in which volume the spot is.
//-----------------------------------------------------------
if (!fNaviSetup)
{
fpNavigator->
SetWorldVolume(G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking()->GetWorldVolume());
fpNavigator->
LocateGlobalPointAndUpdateTouchable(eSpot.GetPosition(),
fpTouchable,
false);
fNaviSetup = true;
}
else
{
fpNavigator->
LocateGlobalPointAndUpdateTouchable(eSpot.GetPosition(),
fpTouchable);
}
//--------------------------------------
// Fills attribute of the G4Step needed
// by our sensitive detector:
//-------------------------------------
// set touchable volume at PreStepPoint:
fFakePreStepPoint->SetTouchable(fpTouchable);
// set total energy deposit:
fFakeStep->SetTotalEnergyDeposit(eSpot.GetEnergy());
}
@@ -0,0 +1,74 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05EnergySpot.cc,v 2.3 1998/12/10 04:11:29 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05EnergySpot.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4Polyline.hh"
#include "G4VVisManager.hh"
#include "G4Step.hh"
ExN05EnergySpot::ExN05EnergySpot()
{;}
ExN05EnergySpot::ExN05EnergySpot(const G4ThreeVector& point, G4double E)
{
Point = point;
Energy = E;
}
ExN05EnergySpot::~ExN05EnergySpot()
{;}
void ExN05EnergySpot::Draw(G4Colour *color)
{
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if (pVVisManager)
{
G4Polyline polyline;
G4Colour colour(1.,.5,.5);
if (color != 0) colour = *color;
G4VisAttributes attribs(colour);
polyline.SetVisAttributes(colour);
G4ThreeVector pp(Point);
// Draw a "home made" marker:
// Will be better by using a real Marker:
pp.setZ(pp.z()+1*cm);
polyline.append(pp);
pp.setZ(pp.z()-2*cm);
polyline.append(pp);
pp = Point;
polyline.append(pp);
pp.setX(pp.x()+1*cm);
polyline.append(pp);
pp.setX(pp.x()-2*cm);
polyline.append(pp);
pp = Point;
polyline.append(pp);
pp.setY(pp.y()+1*cm);
polyline.append(pp);
pp.setY(pp.y()-2*cm);
polyline.append(pp);
pVVisManager -> Draw(polyline);
}
}
void ExN05EnergySpot::Print()
{
G4cout << " ExN05EnergySpot {E = " << Energy << "; Position = " << Point << " }"<< endl;
}
+106
View File
@@ -0,0 +1,106 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05EventAction.cc,v 2.7 1998/12/11 19:14:07 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05EventAction.hh"
#include "ExN05EventActionMessenger.hh"
#include "ExN05CalorimeterHit.hh"
#include "G4Event.hh"
#include "G4EventManager.hh"
#include "G4HCofThisEvent.hh"
#include "G4VHitsCollection.hh"
#include "G4TrajectoryContainer.hh"
#include "G4Trajectory.hh"
#include "G4VVisManager.hh"
#include "G4SDManager.hh"
#include "G4UImanager.hh"
#include <rw/tvordvec.h>
#include "G4ios.hh"
ExN05EventAction::ExN05EventAction()
:drawFlag(false)
{
new ExN05EventActionMessenger(this);
}
ExN05EventAction::~ExN05EventAction()
{;}
void ExN05EventAction::BeginOfEventAction()
{
if(drawFlag)
{
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if(pVVisManager)
{
G4UImanager::GetUIpointer()->ApplyCommand("/vis~/draw/current");
}
}
}
void ExN05EventAction::EndOfEventAction()
{
G4SDManager * SDman = G4SDManager::GetSDMpointer();
G4String colNam;
calorimeterCollID = SDman->GetCollectionID(colNam="CalCollection");
hadCalorimeterCollID = SDman->GetCollectionID(colNam="HadCollection");
const G4Event* evt = fpEventManager->GetConstCurrentEvent();
G4cout << ">>> Event " << evt->GetEventID() << endl;
G4HCofThisEvent * HCE = evt->GetHCofThisEvent();
ExN05CalorimeterHitsCollection* CaloHC = NULL;
ExN05CalorimeterHitsCollection* HadCaloHC = NULL;
if(HCE)
{
CaloHC = (ExN05CalorimeterHitsCollection*)(HCE->GetHC(calorimeterCollID));
HadCaloHC = (ExN05CalorimeterHitsCollection*)(HCE->GetHC(hadCalorimeterCollID));
}
if(CaloHC)
{
int n_hit = CaloHC->entries();
G4cout << " " << n_hit
<< " hits are stored in EM ExN05CalorimeterHitsCollection." << endl;
G4double totE = 0;
for(int i=0;i<n_hit;i++)
{ totE += (*CaloHC)[i]->GetEdep(); }
G4cout << " Total energy deposition in EM calorimeter crytals : "
<< totE / GeV << " (GeV)" << endl;
}
if(HadCaloHC)
{
int n_hit = HadCaloHC->entries();
G4cout << " " << n_hit
<< " hits are stored in HAD ExN05CalorimeterHitsCollection." << endl;
G4double totE = 0;
for(int i=0;i<n_hit;i++)
{ totE += (*HadCaloHC)[i]->GetEdep(); }
G4cout << " Total energy deposition in HAD calorimeter towers : "
<< totE / GeV << " (GeV)" << endl;
}
if(drawFlag)
{
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if(pVVisManager)
{
if(CaloHC) CaloHC->DrawAllHits();
if(HadCaloHC) HadCaloHC->DrawAllHits();
G4UImanager::GetUIpointer()->ApplyCommand("/vis~/show/view");
}
}
}
@@ -0,0 +1,40 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05EventActionMessenger.cc,v 2.1 1998/07/12 02:42:25 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05EventActionMessenger.hh"
#include "ExN05EventAction.hh"
#include "globals.hh"
#include "G4UIcmdWithABool.hh"
ExN05EventActionMessenger::ExN05EventActionMessenger(ExN05EventAction* EA)
:EventAction(EA)
{
// uses "/event" directory already
// defined in G4EvManMessenger
drawEventCmd = new G4UIcmdWithABool("/event/Draw",this);
drawEventCmd->SetGuidance("Set drawFlag to Draw an event. (default = false)");
drawEventCmd->SetParameterName("Draw", false);
drawEventCmd->SetDefaultValue(false);
}
void ExN05EventActionMessenger::SetNewValue(G4UIcommand* command, G4String newValues)
{
if( command->GetCommandName() == "Draw" )
{
G4int vl;
const char* t = newValues;
istrstream is((char*)t);
is >> vl;
EventAction->SetDrawFlag(vl!=0);
}
}
@@ -0,0 +1,75 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05MaxTimeCuts.cc,v 2.3 1998/08/16 14:09:55 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// --------------------------------------------------------------
// 15 April 1998 M.Maire
// --------------------------------------------------------------
#include "ExN05MaxTimeCuts.hh"
#include "G4Step.hh"
#include "G4UserLimits.hh"
#include "G4VParticleChange.hh"
#include "G4EnergyLossTables.hh"
ExN05MaxTimeCuts::ExN05MaxTimeCuts(const G4String& aName)
: ExN05SpecialCuts(aName)
{
if (verboseLevel>1) {
G4cout << GetProcessName() << " is created "<< endl;
}
SetProcessType(fUserDefined);
}
ExN05MaxTimeCuts::~ExN05MaxTimeCuts()
{}
ExN05MaxTimeCuts::ExN05MaxTimeCuts(ExN05MaxTimeCuts& right)
{}
G4double ExN05MaxTimeCuts::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double ,
G4ForceCondition* condition
)
{
// condition is set to "Not Forced"
*condition = NotForced;
G4double proposedStep = DBL_MAX;
// get the pointer to UserLimits
G4UserLimits* pUserLimits = aTrack.GetVolume()->GetLogicalVolume()->GetUserLimits();
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
G4ParticleDefinition* aParticleDef = aTrack.GetDefinition();
if (pUserLimits) {
G4double temp = DBL_MAX;
//max time limit
G4double dTime= (pUserLimits->GetUserMaxTime(aTrack) - aTrack.GetGlobalTime());
if (dTime < 0. ) {
proposedStep = 0.;
} else {
G4double beta = (aParticle->GetTotalMomentum())/(aParticle->GetTotalEnergy());
temp = beta*c_light*dTime;
if (proposedStep > temp) proposedStep = temp;
}
}
return proposedStep;
}
@@ -0,0 +1,82 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05MinEkineCuts.cc,v 2.3 1998/08/16 14:09:56 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// --------------------------------------------------------------
// 15 April 1998 M.Maire
// --------------------------------------------------------------
#include "ExN05MinEkineCuts.hh"
#include "G4Step.hh"
#include "G4UserLimits.hh"
#include "G4VParticleChange.hh"
#include "G4EnergyLossTables.hh"
ExN05MinEkineCuts::ExN05MinEkineCuts(const G4String& aName)
: ExN05SpecialCuts(aName)
{
if (verboseLevel>1) {
G4cout << GetProcessName() << " is created "<< endl;
}
SetProcessType(fUserDefined);
}
ExN05MinEkineCuts::~ExN05MinEkineCuts()
{}
ExN05MinEkineCuts::ExN05MinEkineCuts(ExN05MinEkineCuts& right)
{}
G4double ExN05MinEkineCuts::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double ,
G4ForceCondition* condition
)
{
// condition is set to "Not Forced"
*condition = NotForced;
G4double proposedStep = DBL_MAX;
// get the pointer to UserLimits
G4UserLimits* pUserLimits = aTrack.GetVolume()->GetLogicalVolume()->GetUserLimits();
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
G4ParticleDefinition* aParticleDef = aTrack.GetDefinition();
if (pUserLimits) {
//min kinetic energy
G4double temp = DBL_MAX;
G4double eKine = aParticle->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
G4double eMin = pUserLimits->GetUserMinEkine(aTrack);
G4double rangeNow = DBL_MAX;
if (aParticleDef->GetPDGCharge() != 0.0) {
rangeNow = G4EnergyLossTables::GetRange(aParticleDef,eKine,aMaterial);
}
if (eKine < eMin ) {
proposedStep = 0.;
} else if (aParticleDef->GetPDGCharge() != 0.0) {
// charged particles only
G4double rangeMin = G4EnergyLossTables::GetRange(aParticleDef,eMin,aMaterial);
temp = rangeNow - rangeMin;
if (proposedStep > temp) proposedStep = temp;
}
}
return proposedStep;
}
@@ -0,0 +1,80 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05MinRangeCuts.cc,v 2.3 1998/08/16 14:09:56 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// --------------------------------------------------------------
// 15 April 1998 M.Maire
// --------------------------------------------------------------
#include "ExN05MinRangeCuts.hh"
#include "G4Step.hh"
#include "G4UserLimits.hh"
#include "G4VParticleChange.hh"
#include "G4EnergyLossTables.hh"
ExN05MinRangeCuts::ExN05MinRangeCuts(const G4String& aName)
: ExN05SpecialCuts(aName)
{
if (verboseLevel>1) {
G4cout << GetProcessName() << " is created "<< endl;
}
SetProcessType(fUserDefined);
}
ExN05MinRangeCuts::~ExN05MinRangeCuts()
{}
ExN05MinRangeCuts::ExN05MinRangeCuts(ExN05MinRangeCuts& right)
{}
G4double ExN05MinRangeCuts::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double ,
G4ForceCondition* condition
)
{
// condition is set to "Not Forced"
*condition = NotForced;
G4double proposedStep = DBL_MAX;
// get the pointer to UserLimits
G4UserLimits* pUserLimits = aTrack.GetVolume()->GetLogicalVolume()->GetUserLimits();
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
G4ParticleDefinition* aParticleDef = aTrack.GetDefinition();
if (pUserLimits) {
G4double temp = DBL_MAX;
//min remaining range
G4double eKine = aParticle->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
G4double rangeNow = DBL_MAX;
if (aParticleDef->GetPDGCharge() != 0.0) {
rangeNow = G4EnergyLossTables::GetRange(aParticleDef,eKine,aMaterial);
}
temp = (rangeNow - pUserLimits->GetUserMinRange(aTrack));
if (temp < 0.) {
proposedStep = 0.;
} else {
if (proposedStep > temp) proposedStep = temp;
}
}
return proposedStep;
}
+302
View File
@@ -0,0 +1,302 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05PhysicsList.cc,v 2.7 1998/12/10 04:11:43 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
#include "ExN05PhysicsList.hh"
#include "globals.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleWithCuts.hh"
#include "G4ProcessManager.hh"
#include "G4ProcessVector.hh"
#include "G4ParticleTypes.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "G4ios.hh"
#include <iomanip.h>
#include "G4FastSimulationManagerProcess.hh"
ExN05PhysicsList::ExN05PhysicsList(): G4VUserPhysicsList()
{
SetVerboseLevel(1);
}
ExN05PhysicsList::~ExN05PhysicsList()
{
}
void ExN05PhysicsList::ConstructParticle()
{
// In this method, static member functions should be called
// for all particles which you want to use.
// This ensures that objects of these particle types will be
// created in the program.
ConstructBosons();
ConstructLeptons();
ConstructMesons();
ConstructBarions();
ConstructIons();
}
void ExN05PhysicsList::ConstructBosons()
{
// pseudo-particles
G4Geantino::GeantinoDefinition();
G4ChargedGeantino::ChargedGeantinoDefinition();
// gamma
G4Gamma::GammaDefinition();
// optical photon
G4OpticalPhoton::OpticalPhotonDefinition();
}
#include "G4LeptonConstructor.hh"
void ExN05PhysicsList::ConstructLeptons()
{
// Construct all leptons
G4LeptonConstructor pConstructor;
pConstructor.ConstructParticle();
}
#include "G4MesonConstructor.hh"
void ExN05PhysicsList::ConstructMesons()
{
// Construct all mesons
G4MesonConstructor pConstructor;
pConstructor.ConstructParticle();
}
#include "G4BarionConstructor.hh"
void ExN05PhysicsList::ConstructBarions()
{
// Construct all barions
G4BarionConstructor pConstructor;
pConstructor.ConstructParticle();
}
#include "G4IonConstructor.hh"
void ExN05PhysicsList::ConstructIons()
{
// Construct light ions
G4IonConstructor pConstructor;
pConstructor.ConstructParticle();
}
void ExN05PhysicsList::ConstructProcess()
{
AddTransportation();
AddParameterisation();
ConstructEM();
ConstructLeptHad();
ConstructHad();
ConstructGeneral();
}
#include "ExN05MaxTimeCuts.hh"
#include "ExN05MinEkineCuts.hh"
#include "ExN05MinRangeCuts.hh"
void ExN05PhysicsList::AddTransportation()
{
G4VUserPhysicsList::AddTransportation();
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
pmanager->AddDiscreteProcess(new ExN05MaxTimeCuts());
pmanager->AddDiscreteProcess(new ExN05MinEkineCuts());
pmanager->AddDiscreteProcess(new ExN05MinRangeCuts());
}
}
#include "G4ComptonScattering.hh"
#include "G4GammaConversion.hh"
#include "G4PhotoElectricEffect.hh"
#include "G4MultipleScattering.hh"
#include "G4eIonisation.hh"
#include "G4eBremsstrahlung.hh"
#include "G4eplusAnnihilation.hh"
#include "G4MuIonisation.hh"
#include "G4MuBremsstrahlung.hh"
#include "G4MuPairProduction.hh"
#include "G4hIonisation.hh"
void ExN05PhysicsList::ConstructEM()
{
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
G4String particleName = particle->GetParticleName();
if (particleName == "gamma") {
// gamma
// Construct processes for gamma
pmanager->AddDiscreteProcess(new G4GammaConversion());
pmanager->AddDiscreteProcess(new G4ComptonScattering());
pmanager->AddDiscreteProcess(new G4PhotoElectricEffect());
} else if (particleName == "e-") {
//electron
// Construct processes for electron
G4VProcess* theeminusMultipleScattering = new G4MultipleScattering();
G4VProcess* theeminusIonisation = new G4eIonisation();
G4VProcess* theeminusBremsstrahlung = new G4eBremsstrahlung();
// add processes
pmanager->AddProcess(theeminusMultipleScattering);
pmanager->AddProcess(theeminusIonisation);
pmanager->AddProcess(theeminusBremsstrahlung);
// set ordering for AlongStepDoIt
pmanager->SetProcessOrdering(theeminusMultipleScattering, idxAlongStep, 1);
pmanager->SetProcessOrdering(theeminusIonisation, idxAlongStep, 2);
// set ordering for PostStepDoIt
pmanager->SetProcessOrdering(theeminusMultipleScattering, idxPostStep, 1);
pmanager->SetProcessOrdering(theeminusIonisation, idxPostStep, 2);
pmanager->SetProcessOrdering(theeminusBremsstrahlung, idxPostStep, 3);
} else if (particleName == "e+") {
//positron
// Construct processes for positron
G4VProcess* theeplusMultipleScattering = new G4MultipleScattering();
G4VProcess* theeplusIonisation = new G4eIonisation();
G4VProcess* theeplusBremsstrahlung = new G4eBremsstrahlung();
G4VProcess* theeplusAnnihilation = new G4eplusAnnihilation();
// add processes
pmanager->AddProcess(theeplusMultipleScattering);
pmanager->AddProcess(theeplusIonisation);
pmanager->AddProcess(theeplusBremsstrahlung);
pmanager->AddProcess(theeplusAnnihilation);
// set ordering for AtRestDoIt
pmanager->SetProcessOrderingToFirst(theeplusAnnihilation, idxAtRest);
// set ordering for AlongStepDoIt
pmanager->SetProcessOrdering(theeplusMultipleScattering, idxAlongStep, 1);
pmanager->SetProcessOrdering(theeplusIonisation, idxAlongStep, 2);
// set ordering for PostStepDoIt
pmanager->SetProcessOrdering(theeplusMultipleScattering, idxPostStep, 1);
pmanager->SetProcessOrdering(theeplusIonisation, idxPostStep, 2);
pmanager->SetProcessOrdering(theeplusBremsstrahlung, idxPostStep, 3);
pmanager->SetProcessOrdering(theeplusAnnihilation, idxPostStep, 4);
} else if( particleName == "mu+" ||
particleName == "mu-" ) {
//muon
// Construct processes for muon+
G4VProcess* aMultipleScattering = new G4MultipleScattering();
G4VProcess* aBremsstrahlung = new G4MuBremsstrahlung();
G4VProcess* aPairProduction = new G4MuPairProduction();
G4VProcess* anIonisation = new G4MuIonisation();
// add processes
pmanager->AddProcess(anIonisation);
pmanager->AddProcess(aMultipleScattering);
pmanager->AddProcess(aBremsstrahlung);
pmanager->AddProcess(aPairProduction);
// set ordering for AlongStepDoIt
pmanager->SetProcessOrdering(aMultipleScattering, idxAlongStep, 1);
pmanager->SetProcessOrdering(anIonisation, idxAlongStep, 2);
// set ordering for PostStepDoIt
pmanager->SetProcessOrdering(aMultipleScattering, idxPostStep, 1);
pmanager->SetProcessOrdering(anIonisation, idxPostStep, 2);
pmanager->SetProcessOrdering(aBremsstrahlung, idxPostStep, 3);
pmanager->SetProcessOrdering(aPairProduction, idxPostStep, 4);
} else if ((!particle->IsShortLived()) &&
(particle->GetPDGCharge() != 0.0) &&
(particle->GetParticleName() != "chargedgeantino")) {
// all others charged particles except geantino
G4VProcess* aMultipleScattering = new G4MultipleScattering();
G4VProcess* anIonisation = new G4hIonisation();
// add processes
pmanager->AddProcess(anIonisation);
pmanager->AddProcess(aMultipleScattering);
// set ordering for AlongStepDoIt
pmanager->SetProcessOrdering(aMultipleScattering, idxAlongStep, 1);
pmanager->SetProcessOrdering(anIonisation, idxAlongStep, 2);
// set ordering for PostStepDoIt
pmanager->SetProcessOrdering(aMultipleScattering, idxPostStep, 1);
pmanager->SetProcessOrdering(anIonisation, idxPostStep, 2);
}
}
}
void ExN05PhysicsList::ConstructHad()
{;}
void ExN05PhysicsList::ConstructLeptHad()
{;}
#include "G4Decay.hh"
void ExN05PhysicsList::ConstructGeneral()
{
// Add Decay Process
G4Decay* theDecayProcess = new G4Decay();
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
if (theDecayProcess->IsApplicable(*particle)) {
pmanager ->AddProcess(theDecayProcess);
// set ordering for PostStepDoIt and AtRestDoIt
pmanager ->SetProcessOrdering(theDecayProcess, idxPostStep);
pmanager ->SetProcessOrdering(theDecayProcess, idxAtRest);
}
}
}
void ExN05PhysicsList::AddParameterisation()
{
G4FastSimulationManagerProcess*
theFastSimulationManagerProcess =
new G4FastSimulationManagerProcess();
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
// both postStep and alongStep action are required: because
// of the use of ghost volumes. If no ghost, the postStep
// is sufficient.
pmanager->AddProcess(theFastSimulationManagerProcess, -1, 1, 1);
}
}
void ExN05PhysicsList::SetCuts(G4double cut)
{
if (verboseLevel >0){
G4cout << "ExN05PhysicsList::SetCuts:";
G4cout << "CutLength : " << cut/mm << " (mm)" << endl;
}
// set cut values for gamma at first and for e- second and next for e+,
// because some processes for e+/e- need cut values for gamma
SetCutValue(cut, "gamma");
SetCutValue(cut, "e-");
SetCutValue(cut, "e+");
// set cut values for proton and anti_proton before all other hadrons
// because some processes for hadrons need cut values for proton/anti_proton
SetCutValue(cut, "proton");
SetCutValue(cut, "anti_proton");
SetCutValueForOthers(cut);
if (verboseLevel>1) {
DumpCutValuesTable();
}
}
+133
View File
@@ -0,0 +1,133 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05PiModel.cc,v 2.3 1998/09/07 15:12:32 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05PiModel.hh"
#include "G4PionMinus.hh"
#include "G4PionPlus.hh"
#include "G4Gamma.hh"
ExN05PiModel::ExN05PiModel(G4Envelope *anEnvelope) :
G4VFastSimulationModel("ExN05PiModel",anEnvelope)
{;}
ExN05PiModel::~ExN05PiModel()
{;}
G4bool ExN05PiModel::IsApplicable(const G4ParticleDefinition& particleType)
{
return
&particleType == G4PionMinus::PionMinusDefinition() ||
&particleType == G4PionPlus::PionPlusDefinition();
}
G4bool ExN05PiModel::ModelTrigger(const G4FastTrack& fastTrack) {
//-------------------------------------------------------------
// UserTrigger() method: method which has to decide if
// the parameterisation has to be applied.
// Here ModelTrigger() asks the user (ie you) a 0/1 answer.
//
// Note that quantities like the local/global position/direction etc..
// are available at this level via the fastTrack parameter (allowing
// to check distance from boundaries, see below to allow the decision)
//--------------------------------------------------------------
G4cout << "\nExN05PiModel::ModelTrigger() called:" << endl;
G4cout << "--------------------------------" << endl;
G4cout << "(particle is a " << fastTrack.GetPrimaryTrack()->
GetDefinition()->GetParticleName() << " )\n" << endl;
// -- Examples of available informations:
// -- position:
G4cout << " Track position: " <<
fastTrack.GetPrimaryTrack()->GetPosition() << "(global coord.)" <<
fastTrack.GetPrimaryTrackLocalPosition() << "(in envelope coord.)"
<< endl;
// -- direction:
G4cout << " Track direction:" <<
fastTrack.GetPrimaryTrack()->GetMomentum().unit() <<
"(global coord.)" <<
fastTrack.GetPrimaryTrackLocalDirection() << "(in envelope coord.)" <<
endl;
return true;
}
void ExN05PiModel::DoIt(const G4FastTrack& fastTrack,
G4FastStep& fastStep)
//--------------------------------------------------
//
// User method to code the parameterisation properly
// said.
//
//--------------------------------------------------
{
//------------------------------------------------
// The primary track continues along its direction.
// One secondary (a photon) is added:
//------------------------------------------------
G4cout << " Pion `model' applied\n" << endl;
//------------------------------
// Primary:
// idem as in "DefaultModel":
//
//------------------------------
G4ThreeVector position;
G4double distance;
distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
fastTrack.GetPrimaryTrackLocalDirection());
position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*fastTrack.GetPrimaryTrackLocalDirection();
// -- set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
//---------------------------
// Secondary:
// Adds one "secondary":
//
//---------------------------
// -- First, user has to say how many secondaries will be created:
fastStep.SetNumberOfSecondaryTracks(1);
//------------------------
// -- Build the secondary:
//------------------------
// -- direction:
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
direction.setZ(direction.z()*0.5);
direction.setY(direction.y()+direction.z()*0.1);
direction = direction.unit(); // necessary ?
// -- dynamics (Note that many constructors exists for G4DynamicParticle
// -- see prototype/particle+matter/particles/management/include/G4DynamicParticle.hh)
G4DynamicParticle dynamique(G4Gamma::GammaDefinition(),
direction,
fastTrack.GetPrimaryTrack()->
GetKineticEnergy()/2.);
// -- position:
G4double Dist;
Dist = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
direction);
G4ThreeVector posi;
posi = fastTrack.GetPrimaryTrackLocalPosition() + Dist*direction;
//------------------------------------
//-- Creation of the secondary Track:
//------------------------------------
fastStep.CreateSecondaryTrack(dynamique, posi,
fastTrack.GetPrimaryTrack()->GetGlobalTime());
}
@@ -0,0 +1,211 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05PionShowerModel.cc,v 2.1 1998/12/10 04:05:54 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05PionShowerModel.hh"
#include "ExN05EnergySpot.hh"
#include "Randomize.hh"
#include "G4PionMinus.hh"
#include "G4PionPlus.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
#include "G4Colour.hh"
ExN05PionShowerModel::ExN05PionShowerModel(G4String modelName, G4LogicalVolume* envelope)
: G4VFastSimulationModel(modelName, envelope)
{
fFakeStep = new G4Step();
fFakePreStepPoint = fFakeStep->GetPreStepPoint();
fFakePostStepPoint = fFakeStep->GetPostStepPoint();
fpTouchable = new G4TouchableHistory();
fpNavigator = new G4Navigator();
fNaviSetup = false;
}
ExN05PionShowerModel::ExN05PionShowerModel(G4String modelName)
: G4VFastSimulationModel(modelName)
{
fFakeStep = new G4Step();
fFakePreStepPoint = fFakeStep->GetPreStepPoint();
fFakePostStepPoint = fFakeStep->GetPostStepPoint();
fpTouchable = new G4TouchableHistory();
fpNavigator = new G4Navigator();
fNaviSetup = false;
}
ExN05PionShowerModel::~ExN05PionShowerModel()
{
delete fFakeStep;
delete fpTouchable;
delete fpNavigator;
}
G4bool ExN05PionShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
{
return
&particleType == G4PionMinus::PionMinusDefinition() ||
&particleType == G4PionPlus::PionPlusDefinition();
}
G4bool ExN05PionShowerModel::ModelTrigger(const G4FastTrack& fastTrack)
{
// Applies the parameterisation always: ie as soon as the pion enters the envelope
return true;
}
void ExN05PionShowerModel::DoIt(const G4FastTrack& fastTrack,
G4FastStep& fastStep)
{
// Kill the parawmeterised particle:
fastStep.KillPrimaryTrack();
fastStep.SetPrimaryTrackPathLength(0.0);
fastStep.SetTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
// split into "energy spots" energy according to the shower shape:
Explode(fastTrack);
// and put those energy spots into the crystals:
BuildDetectorResponse();
}
void ExN05PionShowerModel::Explode(const G4FastTrack& fastTrack)
{
//-----------------------------------------------------
// Non-physical shower generated: exp along z and
// transverse.
//-----------------------------------------------------
// center of the shower, we put at the middle of the ghost:
G4ThreeVector showerCenter;
G4double distOut;
distOut = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
fastTrack.GetPrimaryTrackLocalDirection());
showerCenter = fastTrack.GetPrimaryTrackLocalPosition() +
(distOut/2.)*fastTrack.GetPrimaryTrackLocalDirection();
showerCenter = fastTrack.GetInverseAffineTransformation()->
TransformPoint(showerCenter);
// axis of the shower, in global reference frame:
G4ThreeVector xShower, yShower, zShower;
zShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
xShower = zShower.orthogonal();
yShower = zShower.cross(xShower);
// shoot the energy spots:
G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
G4int nSpot = 50;
G4double deposit = Energy/double(nSpot);;
ExN05EnergySpot eSpot;
eSpot.SetEnergy(deposit);
G4ThreeVector ePoint;
G4double z, r, phi;
for (int i = 0; i < nSpot; i++)
{
z = RandGauss::shoot(0,20*cm);
r = RandGauss::shoot(0,10*cm);
phi = RandFlat::shoot()*twopi;
ePoint = showerCenter +
z*zShower +
r*cos(phi)*xShower + r*sin(phi)*yShower;
eSpot.SetPosition(ePoint);
feSpotList.insert(eSpot);
}
}
void ExN05PionShowerModel::BuildDetectorResponse()
{
// Does the assignation of the energy spots to the sensitive volumes:
for (int i = 0; i < feSpotList.entries(); i++)
{
// Draw the energy spot:
G4Colour red(1.,0.,0.);
feSpotList[i].Draw(&red);
// feSpotList[i].Print();
// "converts" the energy spot into the fake
// G4Step to pass to sensitive detector:
AssignSpotAndCallHit(feSpotList[i]);
}
}
void ExN05PionShowerModel::AssignSpotAndCallHit(const ExN05EnergySpot &eSpot)
{
//
// "converts" the energy spot into the fake
// G4Step to pass to sensitive detector:
//
FillFakeStep(eSpot);
//
// call sensitive part: taken/adapted from the stepping:
// Send G4Step information to Hit/Dig if the volume is sensitive
//
G4VPhysicalVolume* pCurrentVolume =
fFakeStep->GetPreStepPoint()->GetPhysicalVolume();
G4VSensitiveDetector* pSensitive;
if( pCurrentVolume != 0 )
{
pSensitive = pCurrentVolume->GetLogicalVolume()->
GetSensitiveDetector();
if( pSensitive != 0 )
{
pSensitive->Hit(fFakeStep);
}
}
}
void ExN05PionShowerModel::FillFakeStep(const ExN05EnergySpot &eSpot)
{
//-----------------------------------------------------------
// find in which volume the spot is.
//-----------------------------------------------------------
if (!fNaviSetup)
{
fpNavigator->
SetWorldVolume(G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking()->GetWorldVolume());
fpNavigator->
LocateGlobalPointAndUpdateTouchable(eSpot.GetPosition(),
fpTouchable,
false);
fNaviSetup = true;
}
else
{
fpNavigator->
LocateGlobalPointAndUpdateTouchable(eSpot.GetPosition(),
fpTouchable);
}
//--------------------------------------
// Fills attribute of the G4Step needed
// by our sensitive detector:
//-------------------------------------
// set touchable volume at PreStepPoint:
fFakePreStepPoint->SetTouchable(fpTouchable);
// set total energy deposit:
fFakeStep->SetTotalEnergyDeposit(eSpot.GetEnergy());
}
@@ -0,0 +1,50 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05PrimaryGeneratorAction.cc,v 2.1 1998/07/12 02:42:27 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05PrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "globals.hh"
ExN05PrimaryGeneratorAction::ExN05PrimaryGeneratorAction()
{
G4int n_particle = 1;
particleGun = new G4ParticleGun(n_particle);
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition* particle
= particleTable->FindParticle(particleName="geantino");
particleGun->SetParticleDefinition(particle);
particleGun->SetParticleMomentumDirection(G4ThreeVector(0.,1.,0.));
particleGun->SetParticleEnergy(100.*GeV);
particleGun->SetParticlePosition(G4ThreeVector(0.*cm,-300.*cm,0.*cm));
}
ExN05PrimaryGeneratorAction::~ExN05PrimaryGeneratorAction()
{
delete particleGun;
}
void ExN05PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
particleGun->GeneratePrimaryVertex(anEvent);
}
G4ParticleGun* ExN05PrimaryGeneratorAction::GetParticleGun()
{
return particleGun;
}
+43
View File
@@ -0,0 +1,43 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05RunAction.cc,v 2.2 1998/07/13 16:34:16 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05RunAction.hh"
#include "G4Run.hh"
#include "G4UImanager.hh"
#include "G4ios.hh"
ExN05RunAction::ExN05RunAction()
{
timer = new G4Timer;
runIDcounter = 0;
}
ExN05RunAction::~ExN05RunAction()
{
delete timer;
}
void ExN05RunAction::BeginOfRunAction(G4Run* aRun)
{
aRun->SetRunID(runIDcounter++);
G4cout << "### Run " << aRun->GetRunID() << " start." << endl;
// timer->Start();
}
void ExN05RunAction::EndOfRunAction(G4Run* aRun)
{
timer->Stop();
G4cout << "number of event = " << aRun->GetNumberOfEvent() << endl;
// << " " << *timer << endl;
}
@@ -0,0 +1,57 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05SpecialCuts.cc,v 2.3 1998/08/16 14:09:57 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// ------------------------------------------------------------
// 15 April 1998 M.Maire
// ------------------------------------------------------------
#include "ExN05SpecialCuts.hh"
#include "G4VParticleChange.hh"
#include "G4Track.hh"
#include "G4Step.hh"
ExN05SpecialCuts::ExN05SpecialCuts(const G4String& aName)
: G4VProcess(aName)
{
if (verboseLevel>1) {
G4cout << GetProcessName() << " is created "<< endl;
}
}
G4VParticleChange* ExN05SpecialCuts::PostStepDoIt(
const G4Track& aTrack,
const G4Step&
)
//
// Stop the current particle, if requested by G4UserLimits
//
{
aParticleChange.Initialize(aTrack);
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetLocalEnergyDeposit (aTrack.GetKineticEnergy()) ;
aParticleChange.SetStatusChange(fStopButAlive);
return &aParticleChange;
}
G4double ExN05SpecialCuts::PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition
)
{
return DBL_MAX;
}
@@ -0,0 +1,51 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05SteppingAction.cc,v 2.0 1998/07/02 14:10:07 gunter Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05SteppingAction.hh"
#include "ExN05SteppingActionMessenger.hh"
#include "G4VVisManager.hh"
#include "G4Polyline.hh"
#include "G4Colour.hh"
#include "G4VisAttributes.hh"
#include "G4SteppingManager.hh"
ExN05SteppingAction::ExN05SteppingAction()
:drawFlag(false)
{
new ExN05SteppingActionMessenger(this);
}
void ExN05SteppingAction::UserSteppingAction()
{
if(drawFlag)
{
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if (pVVisManager) {
const G4SteppingManager* pSM = GetSteppingManager();
G4Polyline polyline;
G4double charge = pSM->GetTrack()->GetDefinition()->GetPDGCharge();
G4Colour colour;
if (charge < 0.) colour = G4Colour(1., 0., 0.);
else if (charge > 0.) colour = G4Colour(0., 0., 1.);
else colour = G4Colour(0., 1., 0.);
G4VisAttributes attribs(colour);
polyline.SetVisAttributes(attribs);
polyline.append(pSM->GetStep()->GetPreStepPoint()->GetPosition());
polyline.append(pSM->GetStep()->GetPostStepPoint()->GetPosition());
pVVisManager -> Draw(polyline);
}
}
}
@@ -0,0 +1,42 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: ExN05SteppingActionMessenger.cc,v 2.2 1998/07/15 12:41:22 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "ExN05SteppingActionMessenger.hh"
#include "ExN05SteppingAction.hh"
#include "globals.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithABool.hh"
ExN05SteppingActionMessenger::ExN05SteppingActionMessenger(ExN05SteppingAction* SA)
:SteppingAction(SA)
{
stepDirectory = new G4UIdirectory("/step/");
stepDirectory->SetGuidance("Step draw control command.");
drawStepCmd = new G4UIcmdWithABool("/step/draw",this);
drawStepCmd->SetGuidance("Draw each step on the fly. (default = true)");
drawStepCmd->SetParameterName("draw", true);
drawStepCmd->SetDefaultValue(true);
}
void ExN05SteppingActionMessenger::SetNewValue(G4UIcommand* command, G4String newValues)
{
if( command->GetCommandName() == "draw" )
{
G4int vl;
const char* t = newValues;
istrstream is((char*)t);
is >> vl;
SteppingAction->SetDrawFlag(vl!=0);
}
}
+73
View File
@@ -0,0 +1,73 @@
// --------------------------------------------
// Adapted from RNGAMA function of the KERNLIB
// Shoot at random according to the gamma
// distribution.
// --------------------------------------------
#include "RandomGamma.hh"
#include <CLHEP/Random/Randomize.h>
double RandomGamma(double p)
{
double h;
double stor[15];
h = 0.;
if (p > 15)
{
while (h <= 0.)
{
double a;
a = RandExponential::shoot();
h = p*(1.-1./(9*p)+a/(3*sqrt(p)));
h = h*h*h;
}
}
else
{
int m = p;
double f = p - m;
if (m > 0)
{
double x = 1.;
RandFlat::shootArray(m, stor);
for (int i = 0; i < m; i++) x *= stor[i];
h = -log(x);
}
if (f >= 0.00001)
{
double x = RandFlat::shoot();
double x1 = -log(x);
if (f >= 0.9999) h += x1;
else
{
x = RandFlat::shoot();
double wlog;
while (1)
{
wlog = log(x)/f;
if (wlog > -100.)
{
double w1 = exp(wlog);
x = RandFlat::shoot();
wlog = log(x)/(1.-f);
if (wlog < -100.)
{
h += x1;
break;
}
else
{
double w = w1 + exp(wlog);
if (w <= 1.)
{
h += w1/w;
break;
}
}
}
}
}
}
}
return h;
}