Import Geant4 10.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2018-12-07 15:15:39 +01:00
parent 6aa23be517
commit db49709b53
11370 changed files with 187480 additions and 160142 deletions
@@ -36,61 +36,61 @@
#include "HadrontherapyLet.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysisFileMessenger::HadrontherapyAnalysisFileMessenger(HadrontherapyAnalysisManager* amgr)
HadrontherapyAnalysisFileMessenger::HadrontherapyAnalysisFileMessenger(HadrontherapyAnalysis* amgr)
:AnalysisManager(amgr)
{
secondaryCmd = new G4UIcmdWithABool("/analysis/secondary",this);
secondaryCmd -> SetParameterName("secondary", true);
secondaryCmd -> SetDefaultValue("true");
secondaryCmd -> SetGuidance("Set if dose/fluence for the secondary particles will be written"
"\n[usage]: /analysis/secondary [true/false]");
secondaryCmd -> AvailableForStates(G4State_Idle, G4State_PreInit);
DoseMatrixCmd = new G4UIcmdWithAString("/analysis/writeDoseFile",this);
DoseMatrixCmd->SetGuidance("Write the dose/fluence to an ASCII file");
DoseMatrixCmd->SetDefaultValue("Dose.out");
DoseMatrixCmd->SetParameterName("choice",true);
{
secondaryCmd = new G4UIcmdWithABool("/analysis/secondary",this);
secondaryCmd -> SetParameterName("secondary", true);
secondaryCmd -> SetDefaultValue("true");
secondaryCmd -> SetGuidance("Set if dose/fluence for the secondary particles will be written"
"\n[usage]: /analysis/secondary [true/false]");
secondaryCmd -> AvailableForStates(G4State_Idle, G4State_PreInit);
DoseMatrixCmd = new G4UIcmdWithAString("/analysis/writeDoseFile",this);
DoseMatrixCmd->SetGuidance("Write the dose/fluence to an ASCII file");
DoseMatrixCmd->SetDefaultValue("Dose.out");
DoseMatrixCmd->SetParameterName("choice",true);
LetCmd = new G4UIcmdWithABool("/analysis/computeLet",this);
LetCmd -> SetParameterName("choice",true);
LetCmd -> SetDefaultValue(true);
LetCmd -> SetGuidance("Set if Let must be computed and write the ASCII filename for the Let");
LetCmd -> AvailableForStates(G4State_Idle, G4State_PreInit);
LetCmd -> SetParameterName("choice",true);
LetCmd -> SetDefaultValue(true);
LetCmd -> SetGuidance("Set if Let must be computed and write the ASCII filename for the Let");
LetCmd -> AvailableForStates(G4State_Idle, G4State_PreInit);
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysisFileMessenger::~HadrontherapyAnalysisFileMessenger()
{
delete secondaryCmd;
delete DoseMatrixCmd;
delete LetCmd;
delete secondaryCmd;
delete DoseMatrixCmd;
delete LetCmd;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyAnalysisFileMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
{
if (command == secondaryCmd)
{
if (HadrontherapyMatrix::GetInstance())
{
HadrontherapyMatrix::GetInstance() -> secondary = secondaryCmd -> GetNewBoolValue(newValue);
}
}
else if (command == DoseMatrixCmd) // Filename can be passed here TODO
{
if ( HadrontherapyMatrix * pMatrix = HadrontherapyMatrix::GetInstance() )
{
//pMatrix -> TotalEnergyDeposit();
pMatrix -> StoreDoseFluenceAscii(newValue);
}
if (HadrontherapyMatrix::GetInstance())
{
HadrontherapyMatrix::GetInstance() -> secondary = secondaryCmd -> GetNewBoolValue(newValue);
}
}
else if (command == LetCmd)
else if (command == DoseMatrixCmd) // Filename can be passed here TODO
{
if (HadrontherapyLet::GetInstance())
HadrontherapyLet::GetInstance() -> doCalculation = LetCmd -> GetNewBoolValue(newValue);
if ( HadrontherapyMatrix * pMatrix = HadrontherapyMatrix::GetInstance() )
{
//pMatrix -> TotalEnergyDeposit();
pMatrix -> StoreDoseFluenceAscii(newValue);
}
}
else if (command == LetCmd)
{
if (HadrontherapyLet::GetInstance())
HadrontherapyLet::GetInstance() -> doCalculation = LetCmd -> GetNewBoolValue(newValue);
}
}
@@ -52,9 +52,10 @@
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyLet.hh"
#include "PassiveProtonBeamLine.hh"
#include "TrentoPassiveProtonBeamLine.hh"
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyRBE.hh"
#include "G4SystemOfUnits.hh"
#include <cmath>
@@ -71,7 +72,7 @@ phantomLogicalVolume(0), detectorLogicalVolume(0),
phantomPhysicalVolume(0), detectorPhysicalVolume(0),
aRegion(0)
{
HadrontherapyAnalysisManager::GetInstance();
/* NOTE! that the HadrontherapyDetectorConstruction class
* does NOT inherit from G4VUserDetectorConstruction G4 class
@@ -103,6 +104,8 @@ aRegion(0)
// Write virtual parameters to the real ones and check for consistency
UpdateGeometry();
}
/////////////////////////////////////////////////////////////////////////////
@@ -206,6 +209,7 @@ void HadrontherapyDetectorConstruction::ConstructDetector()
//skyBlue -> SetForceWireframe(true);
detectorLogicalVolume -> SetVisAttributes(skyBlue);
// **************
// **************
// Cut per Region
// **************
@@ -234,6 +238,42 @@ void HadrontherapyDetectorConstruction::InitializeDetectorROGeometry(
numberOfVoxelsAlongY,
numberOfVoxelsAlongZ);
}
void HadrontherapyDetectorConstruction::VirtualLayer(G4bool Varbool)
{
//Virtual plane
VirtualLayerPosition = G4ThreeVector(0*cm,0*cm,0*cm);
NewSource= Varbool;
if(NewSource == true)
{
// std::cout<<"trr"<<std::endl;
G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR");
solidVirtualLayer = new G4Box("VirtualLayer",
1.*um,
20.*cm,
40.*cm);
logicVirtualLayer = new G4LogicalVolume(
solidVirtualLayer,
airNist,
"VirtualLayer");
physVirtualLayer= new G4PVPlacement(0,VirtualLayerPosition,
"VirtualLayer",
logicVirtualLayer,
motherPhys,
false,
0);
logicVirtualLayer -> SetVisAttributes(skyBlue);
}
}
///////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorConstruction::ParametersCheck()
@@ -327,6 +367,13 @@ void HadrontherapyDetectorConstruction::SetDetectorToPhantomPosition(G4ThreeVect
detectorToPhantomPosition = displ;
}
void HadrontherapyDetectorConstruction::SetVirtualLayerPosition(G4ThreeVector position)
{
VirtualLayerPosition = position;
physVirtualLayer->SetTranslation(VirtualLayerPosition);
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorConstruction::UpdateGeometry()
{
@@ -341,21 +388,40 @@ void HadrontherapyDetectorConstruction::UpdateGeometry()
phantom -> SetXHalfLength(phantomSizeX/2);
phantom -> SetYHalfLength(phantomSizeY/2);
phantom -> SetZHalfLength(phantomSizeZ/2);
phantomPhysicalVolume -> SetTranslation(phantomPosition);
}
else ConstructPhantom();
// Get the center of the detector
SetDetectorPosition();
if (detector)
{
detector -> SetXHalfLength(detectorSizeX/2);
detector -> SetYHalfLength(detectorSizeY/2);
detector -> SetZHalfLength(detectorSizeZ/2);
detectorPhysicalVolume -> SetTranslation(detectorPosition);
}
else ConstructDetector();
//std::cout<<NewSource<<std::endl;
/*if(NewSource)
{
std::cout<<"via"<<std::endl;
}*/
// std::cout<<"i"<<std::endl;
// std::cout<<VirtualLayerPosition<<std::endl;
// physVirtualLayer->SetTranslation(VirtualLayerPosition);
// Round to nearest integer number of voxel
numberOfVoxelsAlongX = G4lrint(detectorSizeX / sizeOfVoxelAlongX);
@@ -393,6 +459,9 @@ void HadrontherapyDetectorConstruction::UpdateGeometry()
massOfVoxel);
// Initialize RBE
HadrontherapyRBE::CreateInstance(numberOfVoxelsAlongX, numberOfVoxelsAlongY, numberOfVoxelsAlongZ, massOfVoxel);
// Comment out the line below if let calculation is not needed!
// Initialize LET with energy of primaries and clear data inside
if ( (let = HadrontherapyLet::GetInstance(this)) )
@@ -407,6 +476,7 @@ void HadrontherapyDetectorConstruction::UpdateGeometry()
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
PrintParameters();
// CheckOverlaps();
}
@@ -458,3 +528,4 @@ void HadrontherapyDetectorConstruction::PrintParameters()
numberOfVoxelsAlongZ << ')' << G4endl;
}
@@ -37,136 +37,176 @@
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorMessenger::HadrontherapyDetectorMessenger(HadrontherapyDetectorConstruction* detector)
:hadrontherapyDetector(detector)
:hadrontherapyDetector(detector)
{
// Change Phantom size
changeThePhantomDir = new G4UIdirectory("/changePhantom/");
changeThePhantomDir -> SetGuidance("Command to change the Phantom Size/position");
changeThePhantomSizeCmd = new G4UIcmdWith3VectorAndUnit("/changePhantom/size", this);
changeThePhantomSizeCmd -> SetGuidance("Insert sizes X Y and Z"
"\n 0 or negative values mean <<Don't change it!>>");
changeThePhantomSizeCmd -> SetParameterName("PhantomSizeAlongX",
"PhantomSizeAlongY",
"PhantomSizeAlongZ", false);
"\n 0 or negative values mean <<Don't change it!>>");
changeThePhantomSizeCmd -> SetParameterName("PhantomSizeAlongX",
"PhantomSizeAlongY",
"PhantomSizeAlongZ", false);
changeThePhantomSizeCmd -> SetDefaultUnit("mm");
changeThePhantomSizeCmd -> SetUnitCandidates("nm um mm cm");
changeThePhantomSizeCmd -> SetUnitCandidates("nm um mm cm");
changeThePhantomSizeCmd -> AvailableForStates(G4State_Idle);
// Change Phantom material
// Change Phantom material
changeThePhantomMaterialCmd = new G4UIcmdWithAString("/changePhantom/material", this);
changeThePhantomMaterialCmd -> SetGuidance("Change the Phantom and the detector material");
changeThePhantomMaterialCmd -> SetGuidance("Change the Phantom and the detector material");
changeThePhantomMaterialCmd -> SetParameterName("PhantomMaterial", false);
changeThePhantomMaterialCmd -> SetDefaultValue("G4_WATER");
changeThePhantomMaterialCmd -> AvailableForStates(G4State_Idle);
// Change Phantom position
changeThePhantomPositionCmd = new G4UIcmdWith3VectorAndUnit("/changePhantom/position", this);
changeThePhantomPositionCmd -> SetGuidance("Insert X Y and Z dimensions for the position of the center of the Phantom"
" respect to that of the \"World\"");
changeThePhantomPositionCmd -> SetParameterName("PositionAlongX",
"PositionAlongY",
"PositionAlongZ", false);
" respect to that of the \"World\"");
changeThePhantomPositionCmd -> SetParameterName("PositionAlongX",
"PositionAlongY",
"PositionAlongZ", false);
changeThePhantomPositionCmd -> SetDefaultUnit("mm");
changeThePhantomPositionCmd -> SetUnitCandidates("um mm cm m");
changeThePhantomPositionCmd -> SetUnitCandidates("um mm cm m");
changeThePhantomPositionCmd -> AvailableForStates(G4State_Idle);
updateCmd = new G4UIcmdWithoutParameter("/changePhantom/update",this);
updateCmd->SetGuidance("Update Phantom/Detector geometry.");
updateCmd->SetGuidance("This command MUST be applied before \"beamOn\" ");
updateCmd->SetGuidance("if you changed geometrical value(s).");
updateCmd->AvailableForStates(G4State_Idle);
// Change detector size
changeTheDetectorDir = new G4UIdirectory("/changeDetector/");
changeTheDetectorDir -> SetGuidance("Command to change the Detector's Size/position/Voxels");
changeTheDetectorSizeCmd = new G4UIcmdWith3VectorAndUnit("/changeDetector/size",this);
changeTheDetectorSizeCmd -> SetGuidance("Insert sizes for X Y and Z dimensions of the Detector"
"\n 0 or negative values mean <<Don't change it>>");
"\n 0 or negative values mean <<Don't change it>>");
changeTheDetectorSizeCmd -> SetParameterName("DetectorSizeAlongX", "DetectorSizeAlongY", "DetectorSizeAlongZ", false);
changeTheDetectorSizeCmd -> SetDefaultUnit("mm");
changeTheDetectorSizeCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorSizeCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorSizeCmd -> AvailableForStates(G4State_Idle);
// Change the detector to phantom displacement
changeTheDetectorToPhantomPositionCmd = new G4UIcmdWith3VectorAndUnit("/changeDetector/displacement",this);
changeTheDetectorToPhantomPositionCmd -> SetGuidance("Insert X Y and Z displacements between Detector and Phantom"
"\nNegative values mean <<Don't change it!>>");
"\nNegative values mean <<Don't change it!>>");
changeTheDetectorToPhantomPositionCmd -> SetParameterName("DisplacementAlongX",
"DisplacementAlongY",
"DisplacementAlongZ", false);
"DisplacementAlongY",
"DisplacementAlongZ", false);
changeTheDetectorToPhantomPositionCmd -> SetDefaultUnit("mm");
changeTheDetectorToPhantomPositionCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorToPhantomPositionCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorToPhantomPositionCmd -> AvailableForStates(G4State_Idle);
// Change voxels by its size
changeTheDetectorVoxelCmd = new G4UIcmdWith3VectorAndUnit("/changeDetector/voxelSize",this);
changeTheDetectorVoxelCmd -> SetGuidance("Insert Voxel sizes for X Y and Z dimensions"
"\n 0 or negative values mean <<Don't change it!>>");
"\n 0 or negative values mean <<Don't change it!>>");
changeTheDetectorVoxelCmd -> SetParameterName("VoxelSizeAlongX", "VoxelSizeAlongY", "VoxelSizeAlongZ", false);
changeTheDetectorVoxelCmd -> SetDefaultUnit("mm");
changeTheDetectorVoxelCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorVoxelCmd -> AvailableForStates(G4State_Idle);
changeTheSource = new G4UIdirectory("/changeTheSource/");
changeTheSource -> SetGuidance("Command to change the source");
/////////////////////////////////////////////////////////////////////////////
VirtualLayer = new G4UIcmdWithABool("/changeTheSource/VirtualLayer",this);
VirtualLayer -> SetParameterName("VirtualLayer ", false);
VirtualLayer -> SetDefaultValue("false");
VirtualLayer -> SetGuidance("Set if you want place a VirtualLayer"
"\n[usage]: /changeTheSource/VirtualLayer [true/false]");
VirtualLayer -> AvailableForStates(G4State_Idle, G4State_PreInit);
VirtualLayerPosition = new G4UIcmdWith3VectorAndUnit("/changeTheSource/VirtualLayerPosition", this);
VirtualLayerPosition -> SetGuidance("Insert X Y and Z dimensions for the position of the center of the Virtual Layer"
" respect to that of the \"World\"");
VirtualLayerPosition -> SetParameterName("PositionAlongX",
"PositionAlongY",
"PositionAlongZ", false);
VirtualLayerPosition -> SetDefaultUnit("cm");
VirtualLayerPosition -> SetUnitCandidates("um mm cm m");
VirtualLayerPosition -> AvailableForStates(G4State_Idle);
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorMessenger::~HadrontherapyDetectorMessenger()
{
delete changeThePhantomDir;
delete changeThePhantomSizeCmd;
delete changeThePhantomPositionCmd;
delete changeThePhantomMaterialCmd;
delete changeThePhantomDir;
delete changeThePhantomSizeCmd;
delete changeThePhantomPositionCmd;
delete changeThePhantomMaterialCmd;
delete updateCmd;
delete changeTheDetectorDir;
delete changeTheDetectorSizeCmd;
delete changeTheDetectorToPhantomPositionCmd;
delete changeTheDetectorDir;
delete changeTheDetectorSizeCmd;
delete changeTheDetectorToPhantomPositionCmd;
delete changeTheDetectorVoxelCmd;
delete VirtualLayer;
delete VirtualLayerPosition;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == changeThePhantomSizeCmd)
if( command == changeThePhantomSizeCmd)
{
G4ThreeVector size = changeThePhantomSizeCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetPhantomSize(size.getX(),size.getY(),size.getZ());
G4ThreeVector size = changeThePhantomSizeCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetPhantomSize(size.getX(),size.getY(),size.getZ());
}
else if (command == changeThePhantomPositionCmd )
{
G4ThreeVector size = changeThePhantomPositionCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetPhantomPosition(size);
}
else if (command == changeThePhantomMaterialCmd)
{
hadrontherapyDetector -> SetPhantomMaterial(newValue);
}
else if (command == changeTheDetectorSizeCmd)
{
G4ThreeVector size = changeTheDetectorSizeCmd -> GetNew3VectorValue(newValue);
else if (command == changeThePhantomPositionCmd )
{
G4ThreeVector size = changeThePhantomPositionCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetPhantomPosition(size);
}
else if (command == changeThePhantomMaterialCmd)
{
hadrontherapyDetector -> SetPhantomMaterial(newValue);
}
else if (command == changeTheDetectorSizeCmd)
{
G4ThreeVector size = changeTheDetectorSizeCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetDetectorSize(size.getX(),size.getY(),size.getZ());
}
else if (command == changeTheDetectorToPhantomPositionCmd)
{
G4ThreeVector size = changeTheDetectorToPhantomPositionCmd-> GetNew3VectorValue(newValue);
}
else if (command == changeTheDetectorToPhantomPositionCmd)
{
G4ThreeVector size = changeTheDetectorToPhantomPositionCmd-> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetDetectorToPhantomPosition(size);
}
else if (command == changeTheDetectorVoxelCmd)
{
G4ThreeVector size = changeTheDetectorVoxelCmd -> GetNew3VectorValue(newValue);
}
else if (command == changeTheDetectorVoxelCmd)
{
G4ThreeVector size = changeTheDetectorVoxelCmd -> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetVoxelSize(size.getX(),size.getY(),size.getZ());
}
else if (command == updateCmd)
{
hadrontherapyDetector -> UpdateGeometry();
}
}
else if (command == updateCmd)
{
hadrontherapyDetector -> UpdateGeometry();
}
else if(command == VirtualLayer)
{
hadrontherapyDetector->VirtualLayer(VirtualLayer->GetNewBoolValue(newValue));
}
else if(command == VirtualLayerPosition)
{
G4ThreeVector size = VirtualLayerPosition-> GetNew3VectorValue(newValue);
hadrontherapyDetector -> SetVirtualLayerPosition(size);
}
}
@@ -320,12 +320,13 @@ void HadrontherapyDetectorROGeometry::Construct()
void HadrontherapyDetectorROGeometry::ConstructSD()
{
G4String sensitiveDetectorName = "RODetector";
HadrontherapyDetectorSD* detectorSD = new HadrontherapyDetectorSD(sensitiveDetectorName);
G4SDManager::GetSDMpointer()->AddNewDetector(detectorSD);
sensitiveLogicalVolume->SetSensitiveDetector(detectorSD);
SetSensitiveDetector(sensitiveLogicalVolume,detectorSD);
// SetSensitiveDetector(sensitiveLogicalVolume,detectorSD);
}
@@ -71,8 +71,7 @@ G4VSensitiveDetector(name)
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorSD::~HadrontherapyDetectorSD()
{
}
{}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorSD::Initialize(G4HCofThisEvent*)
@@ -92,12 +91,12 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
// Get kinetic energy
G4Track * theTrack = aStep -> GetTrack();
G4double kineticEnergy = theTrack -> GetKineticEnergy();
G4ParticleDefinition *particleDef = theTrack -> GetDefinition();
//Get particle name
G4String particleName = particleDef -> GetParticleName();
// Get particle PDG code
G4int pdg = particleDef ->GetPDGEncoding();
// Get unique track_id (in an event)
@@ -119,13 +118,15 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
G4String namePre = volumePre->GetName();
//G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance();
HadrontherapyLet* let = HadrontherapyLet::GetInstance();
G4int* hitTrack = matrix -> GetHitTrack(i,j,k);
G4int* hitTrack = matrix -> GetHitTrack(i,j,k);
// ******************** let ***************************
@@ -133,17 +134,50 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
{
if ( !(Z==0 && A==1) ) // All but not neutrons
{
if( energyDeposit>0. && DX >0. )
if( energyDeposit>0. && DX >0. )// calculate only energy deposit
{
if (pdg !=22) // not gamma
if (pdg !=22 && pdg !=11) // not gamma and electrons
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i, j, k);
// Get the pre-step kinetic energy
G4double eKinPre = aStep -> GetPreStepPoint() -> GetKineticEnergy();
// Get the post-step kinetic energy
G4double eKinPost = aStep -> GetPostStepPoint() -> GetKineticEnergy();
// Get the step average kinetic energy
G4double eKinMean = (eKinPre + eKinPost) * 0.5;
// get the material
G4Material * materialStep = aStep -> GetPreStepPoint() -> GetMaterial();
// get the secondary paticles
G4Step fstep = *theTrack -> GetStep();
// store all the secondary partilce in current step
const std::vector<const G4Track*> * secondary = fstep.GetSecondaryInCurrentStep();
size_t SecondarySize = (*secondary).size();
G4double EnergySecondary = 0.;
// get secondary electrons energy deposited
if (SecondarySize) // calculate only secondary particles
{
for (size_t numsec = 0; numsec< SecondarySize ; numsec ++)
{
//Get the PDG code of every secondaty particles in current step
G4int PDGSecondary=(*secondary)[numsec]->GetDefinition()->GetPDGEncoding();
if(PDGSecondary == 11) // calculate only secondary electrons
{
// calculate the energy deposit of secondary electrons in current step
EnergySecondary += (*secondary)[numsec]->GetKineticEnergy();
}
}
}
// call the let filldatas function to calculate let
let -> FillEnergySpectrum(trackID, particleDef, eKinMean, materialStep,
energyDeposit,EnergySecondary,DX, i, j, k);
}
else if (kineticEnergy > 50.*keV) // gamma cut
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i , j, k);
}
}
}
}
@@ -181,7 +215,7 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
* Create a hit with the information of position is in the detector
*/
HadrontherapyDetectorHit* detectorHit = new HadrontherapyDetectorHit();
detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit);
detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit);
HitsCollection -> insert(detectorHit);
}
}
@@ -194,8 +228,8 @@ void HadrontherapyDetectorSD::EndOfEvent(G4HCofThisEvent* HCE)
static G4int HCID = -1;
if(HCID < 0)
{
HCID = GetCollectionID(0);
{
HCID = GetCollectionID(0);
}
HCE -> AddHitsCollection(HCID,HitsCollection);
@@ -91,10 +91,9 @@ void HadrontherapyEventAction::EndOfEventAction(const G4Event* evt)
G4int j = ((*CHC)[h]) -> GetYID();
G4int k = ((*CHC)[h]) -> GetZID();
G4double energyDeposit = ((*CHC)[h]) -> GetEdep();
matrix -> Fill(i, j, k, energyDeposit/MeV);
matrix -> Fill(i, j, k, energyDeposit/MeV);
}
}
}
}
}
@@ -30,14 +30,13 @@
#include "HadrontherapyDetectorConstruction.hh"
#include "HadrontherapyInteractionParameters.hh"
#include "HadrontherapyDetectorROGeometry.hh"
#include "HadrontherapyTIFPAPassiveProtonBeamLine.hh"
#include "PassiveProtonBeamLine.hh"
#include "PassiveCarbonBeamLine.hh"
#include "LaserDrivenBeamLine.hh"
#include "G4RunManager.hh"
#include "G4VUserParallelWorld.hh"
#include "G4ThreeVector.hh"
#include "TrentoPassiveProtonBeamLine.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyGeometryController::HadrontherapyGeometryController()
@@ -42,26 +42,26 @@ G4bool HadrontherapyLet::doCalculation = false;
HadrontherapyLet* HadrontherapyLet::GetInstance(HadrontherapyDetectorConstruction *pDet)
{
if (instance) delete instance;
instance = new HadrontherapyLet(pDet);
return instance;
if (instance) delete instance;
instance = new HadrontherapyLet(pDet);
return instance;
}
HadrontherapyLet* HadrontherapyLet::GetInstance()
{
return instance;
return instance;
}
HadrontherapyLet::HadrontherapyLet(HadrontherapyDetectorConstruction* pDet)
:filename("Let.out"),matrix(0) // Default output filename
:filename("Let.out"),matrix(0) // Default output filename
{
matrix = HadrontherapyMatrix::GetInstance();
if (!matrix)
G4Exception("HadrontherapyLet::HadrontherapyLet",
"Hadrontherapy0005", FatalException,
"HadrontherapyMatrix not found. Firstly create an instance of it.");
if (!matrix)
G4Exception("HadrontherapyLet::HadrontherapyLet",
"Hadrontherapy0005", FatalException,
"HadrontherapyMatrix not found. Firstly create an instance of it.");
nVoxels = matrix -> GetNvoxel();
@@ -77,94 +77,122 @@ HadrontherapyLet::HadrontherapyLet(HadrontherapyDetectorConstruction* pDet)
// Instances for Total LET
totalLetD = new G4double[nVoxels];
DtotalLetD = new G4double[nVoxels];
totalLetT = new G4double[nVoxels];
DtotalLetT = new G4double[nVoxels];
}
HadrontherapyLet::~HadrontherapyLet()
{
Clear();
delete [] totalLetD;
delete [] DtotalLetD;
Clear();
delete [] totalLetD;
delete [] DtotalLetD;
delete [] totalLetT;
delete [] DtotalLetT;
}
// Fill energy spectrum for every voxel (local energy spectrum)
void HadrontherapyLet::Initialize()
{
for(G4int v=0; v < nVoxels; v++) totalLetD[v] = DtotalLetD[v] = 0.;
Clear();
for(G4int v=0; v < nVoxels; v++) totalLetD[v] = DtotalLetD[v] = totalLetT[v] = DtotalLetT[v] = 0.;
Clear();
}
/**
* Clear all stored data
*/
void HadrontherapyLet::Clear()
{
for (size_t i=0; i < ionLetStore.size(); i++)
{
delete [] ionLetStore[i].letDN;
delete [] ionLetStore[i].letDD;
}
ionLetStore.clear();
for (size_t i=0; i < ionLetStore.size(); i++)
{
delete [] ionLetStore[i].letDN; // Let Dose Numerator
delete [] ionLetStore[i].letDD; // Let Dose Denominator
delete [] ionLetStore[i].letTN; // Let Track Numerator
delete [] ionLetStore[i].letTD; // Let Track Denominator
}
ionLetStore.clear();
}
void HadrontherapyLet::FillEnergySpectrum(G4int trackID,
G4ParticleDefinition* particleDef,
/*G4double kinEnergy,*/
G4double ekinMean,
G4Material* mat,
G4double DE,
G4double DEEletrons,
G4double DX,
G4int i, G4int j, G4int k)
{
if (DE <= 0. || DX <=0.) return;
if (!doCalculation) return;
G4int Z = particleDef -> GetAtomicNumber();
if (DE <= 0. || DX <=0. ) return; // calculate only energy deposit
if (!doCalculation) return;
// atomic number
G4int Z = particleDef -> GetAtomicNumber();
if (Z<1) return; // calculate only protons and ions
G4int PDGencoding = particleDef -> GetPDGEncoding();
PDGencoding -= PDGencoding%10; // simple Particle data group id without excitation level
G4int voxel = matrix -> Index(i,j,k);
// ICRU stopping power calculation
G4EmCalculator emCal;
// use the mean kinetic energy of ions in a step to calculate ICRU stopping power
G4double Lsn = emCal.ComputeElectronicDEDX(ekinMean, particleDef, mat);
G4int PDGencoding = particleDef -> GetPDGEncoding();
PDGencoding -= PDGencoding%10;
// Total LET calculation...
totalLetD[voxel] += (DE + DEEletrons) * Lsn; // total dose Let Numerator, including secondary electrons energy deposit
DtotalLetD[voxel] += DE + DEEletrons; // total dose Let Denominator, including secondary electrons energy deposit
totalLetT[voxel] += DX * Lsn; // total track Let Numerator
DtotalLetT[voxel] += DX; // total track Let Denominator
G4int voxel = matrix -> Index(i,j,k);
// Total LET calculation...
totalLetD[voxel] += DE*(DE/DX);
DtotalLetD[voxel] += DE;
// Single ion LET
if (Z>=1)
{
// Search for already allocated data...
size_t l;
for (l=0; l < ionLetStore.size(); l++)
{
if (ionLetStore[l].PDGencoding == PDGencoding)
if ( ((trackID ==1) && (ionLetStore[l].isPrimary)) || ((trackID !=1) && (!ionLetStore[l].isPrimary)))
break;
}
// store primary ions and secondary ions
size_t l;
for (l=0; l < ionLetStore.size(); l++)
{
// judge species of the current particle and store it
if (ionLetStore[l].PDGencoding == PDGencoding)
if ( ((trackID ==1) && (ionLetStore[l].isPrimary)) || ((trackID !=1) && (!ionLetStore[l].isPrimary)))
break;
}
if (l == ionLetStore.size()) // Just another type of ion/particle for our store...
{
// mass number
G4int A = particleDef -> GetAtomicMass();
if (l == ionLetStore.size()) // Just another type of ion/particle for our store...
{
G4int A = particleDef -> GetAtomicMass();
G4String fullName = particleDef -> GetParticleName();
G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy [x.y]
ionLet ion =
{
(trackID == 1) ? true:false, // is it the primary particle?
PDGencoding,
fullName,
name,
Z,
A,
new G4double[nVoxels], // Let Dose Numerator
new G4double[nVoxels] // Let Dose Denominator
};
// Initialize let
for(G4int v=0; v < nVoxels; v++) ion.letDN[v] = ion.letDD[v] = 0.;
ionLetStore.push_back(ion);
//G4cout << "Allocated LET data for " << ion.name << G4endl;
}
ionLetStore[l].letDN[voxel] += DE*(DE/DX);
ionLetStore[l].letDD[voxel] += DE;
}
// particle name
G4String fullName = particleDef -> GetParticleName();
G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy [x.y]
ionLet ion =
{
(trackID == 1) ? true:false, // is it the primary particle?
PDGencoding,
fullName,
name,
Z,
A,
new G4double[nVoxels], // Let Dose Numerator
new G4double[nVoxels], // Let Dose Denominator
new G4double[nVoxels], // Let Track Numerator
new G4double[nVoxels], // Let Track Denominator
};
// Initialize let and other parameters
for(G4int v=0; v < nVoxels; v++)
{
ion.letDN[v] = ion.letDD[v] = ion.letTN[v] = ion.letTD[v] = 0.;
}
ionLetStore.push_back(ion);
}
// calculate ions let and store them
ionLetStore[l].letDN[voxel] += (DE + DEEletrons)* Lsn; // ions dose Let Numerator, including secondary electrons energy deposit
ionLetStore[l].letDD[voxel] += DE + DEEletrons; // ions dose Let Denominator, including secondary electrons energy deposit
ionLetStore[l].letTN[voxel] += DX* Lsn; // ions track Let Numerator
ionLetStore[l].letTD[voxel] += DX; // ions track Let Denominator
}
@@ -172,44 +200,59 @@ void HadrontherapyLet::FillEnergySpectrum(G4int trackID,
void HadrontherapyLet::LetOutput()
{
for(G4int v=0; v < nVoxels; v++) if (DtotalLetD[v]>0.) totalLetD[v] = totalLetD[v]/DtotalLetD[v];
// Sort ions by A and then by Z ...
std::sort(ionLetStore.begin(), ionLetStore.end());
// Compute Let Track and Let Dose for any single ion
for(G4int v=0; v < nVoxels; v++)
{
// compute total let
if (DtotalLetD[v]>0.) totalLetD[v] = totalLetD[v]/DtotalLetD[v];
if (DtotalLetT[v]>0.) totalLetT[v] = totalLetT[v]/DtotalLetT[v];
}
for(G4int v=0; v < nVoxels; v++)
{
for (size_t ion=0; ion < ionLetStore.size(); ion++)
{
if (ionLetStore[ion].letDD[v] >0.) ionLetStore[ion].letDN[v] = ionLetStore[ion].letDN[v] / ionLetStore[ion].letDD[v];
}// end loop over ions
}
// Sort ions by A and then by Z ...
std::sort(ionLetStore.begin(), ionLetStore.end());
}// end loop over voxels
// Compute Let Track and Let Dose for ions
for(G4int v=0; v < nVoxels; v++)
{
for (size_t ion=0; ion < ionLetStore.size(); ion++)
{
// compute ions let
if (ionLetStore[ion].letDD[v] >0.) ionLetStore[ion].letDN[v] = ionLetStore[ion].letDN[v] / ionLetStore[ion].letDD[v];
if (ionLetStore[ion].letTD[v] >0.) ionLetStore[ion].letTN[v] = ionLetStore[ion].letTN[v] / ionLetStore[ion].letTD[v];
} // end loop over ions
}
} // end loop over voxels
void HadrontherapyLet::StoreLetAscii()
{
#define width 15L
if(ionLetStore.size())
{
ofs.open(filename, std::ios::out);
if (ofs.is_open())
{
if(ionLetStore.size())
{
ofs.open(filename, std::ios::out);
if (ofs.is_open())
{
// Write the voxels index and the list of particles/ions
ofs << std::setprecision(6) << std::left <<
// Write the voxels index and total Lets and the list of particles/ions
ofs << std::setprecision(6) << std::left <<
"i\tj\tk\t";
ofs << std::setw(width) << "LDT";
for (size_t l=0; l < ionLetStore.size(); l++)
{
G4String a = (ionLetStore[l].isPrimary) ? "_1":"";
ofs << std::setw(width) << ionLetStore[l].name + a ;
}
ofs << G4endl;
ofs << std::setw(width) << "LDT";
ofs << std::setw(width) << "LTT";
// Write data
for (size_t l=0; l < ionLetStore.size(); l++) // write ions name
{
G4String a = (ionLetStore[l].isPrimary) ? "_1_D":"_D";
ofs << std::setw(width) << ionLetStore[l].name + a ;
G4String b = (ionLetStore[l].isPrimary) ? "_1_T":"_T";
ofs << std::setw(width) << ionLetStore[l].name + b ;
}
ofs << G4endl;
// Write data
G4AnalysisManager* LetFragmentTuple = G4AnalysisManager::Instance();
@@ -222,64 +265,72 @@ void HadrontherapyLet::StoreLetAscii()
LetFragmentTuple ->CreateNtuple("coordinate", "Let");
LetFragmentTuple ->CreateNtupleIColumn("i");//1
LetFragmentTuple ->CreateNtupleIColumn("j");//2
LetFragmentTuple ->CreateNtupleIColumn("k");//3
LetFragmentTuple ->CreateNtupleDColumn("TotalLetD");//4
LetFragmentTuple ->CreateNtupleIColumn("i");//0
LetFragmentTuple ->CreateNtupleIColumn("j");//1
LetFragmentTuple ->CreateNtupleIColumn("k");//2
LetFragmentTuple ->CreateNtupleDColumn("TotalLetD");//3
LetFragmentTuple ->CreateNtupleDColumn("TotalLetT");//4
LetFragmentTuple ->CreateNtupleIColumn("A");//5
LetFragmentTuple ->CreateNtupleIColumn("Z");//6
LetFragmentTuple ->CreateNtupleDColumn("IonLETD");//7
LetFragmentTuple ->CreateNtupleDColumn("IonLETT");//8
LetFragmentTuple ->FinishNtuple();
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
LetFragmentTuple->FillNtupleIColumn(1,0, i);
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
LetFragmentTuple->FillNtupleIColumn(1,0, i);
LetFragmentTuple->FillNtupleIColumn(1,1, j);
LetFragmentTuple->FillNtupleIColumn(1,2, k);
G4int v = matrix -> Index(i, j, k);
for (size_t l=0; l < ionLetStore.size(); l++)
{
// Write only not identically null data lines
// write total Lets and voxels index
ofs << G4endl;
ofs << i << '\t' << j << '\t' << k << '\t';
ofs << std::setw(width) << totalLetD[v]/(keV/um);
ofs << std::setw(width) << totalLetT[v]/(keV/um);
// write ions Lets
for (size_t l=0; l < ionLetStore.size(); l++)
{
// Write only not identically null data line
if(ionLetStore[l].letDN)
{
ofs << G4endl;
ofs << i << '\t' << j << '\t' << k << '\t';
ofs << std::setw(width) << totalLetD[v]/(keV/um);
LetFragmentTuple->FillNtupleDColumn(1,3, totalLetD[v]/(keV/um));
for (size_t ll=0; ll < ionLetStore.size(); ll++)
{
ofs << std::setw(width) << ionLetStore[ll].letDN[v]/(keV/um) ;
LetFragmentTuple->FillNtupleIColumn(1,4, ionLetStore[ll].A);
LetFragmentTuple->FillNtupleIColumn(1,5, ionLetStore[ll].Z);
LetFragmentTuple->FillNtupleDColumn(1,6, ionLetStore[ll].letDN[v]/(keV/um));
LetFragmentTuple->AddNtupleRow(1);
}
break;
}
}
}
ofs.close();
{
// write ions Lets
ofs << std::setw(width) << ionLetStore[l].letDN[v]/(keV/um) ;
ofs << std::setw(width) << ionLetStore[l].letTN[v]/(keV/um);
}
}
LetFragmentTuple->FillNtupleDColumn(1,3, totalLetD[v]/(keV/um));
LetFragmentTuple->FillNtupleDColumn(1,4, totalLetT[v]/(keV/um));
for (size_t ll=0; ll < ionLetStore.size(); ll++)
{
LetFragmentTuple->FillNtupleIColumn(1,5, ionLetStore[ll].A);
LetFragmentTuple->FillNtupleIColumn(1,6, ionLetStore[ll].Z);
LetFragmentTuple->FillNtupleDColumn(1,7, ionLetStore[ll].letDN[v]/(keV/um));
LetFragmentTuple->FillNtupleDColumn(1,8, ionLetStore[ll].letTN[v]/(keV/um));
LetFragmentTuple->AddNtupleRow(1);
}
}
ofs.close();
LetFragmentTuple->Write();
LetFragmentTuple->CloseFile();
}
}
}
}
}
@@ -38,32 +38,31 @@
#include "G4RunManager.hh"
#include "G4ParticleGun.hh"
#include "HadrontherapySteppingAction.hh"
#include "HadrontherapyAnalysisFileMessenger.hh"
#include "G4SystemOfUnits.hh"
#include <time.h>
HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::instance = 0;
HadrontherapyAnalysisManager::HadrontherapyAnalysisManager()
HadrontherapyAnalysis* HadrontherapyAnalysis::instance = 0;
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysis::HadrontherapyAnalysis()
{
fMess = new HadrontherapyAnalysisFileMessenger(this);
}
HadrontherapyAnalysisManager::~HadrontherapyAnalysisManager()
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysis::~HadrontherapyAnalysis()
{
delete fMess;
}
HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::GetInstance(){
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysis* HadrontherapyAnalysis::GetInstance(){
if (instance == 0) instance = new HadrontherapyAnalysisManager;
if (instance == 0) instance = new HadrontherapyAnalysis;
return instance;
}
HadrontherapyMatrix* HadrontherapyMatrix::instance = NULL;
G4bool HadrontherapyMatrix::secondary = false;
@@ -73,6 +72,8 @@ HadrontherapyMatrix* HadrontherapyMatrix::GetInstance()
{
return instance;
}
/////////////////////////////////////////////////////////////////////////////
// This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it
// TODO A check on the parameters is required!
HadrontherapyMatrix* HadrontherapyMatrix::GetInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass)
@@ -83,11 +84,10 @@ HadrontherapyMatrix* HadrontherapyMatrix::GetInstance(G4int voxelX, G4int voxelY
return instance;
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyMatrix::HadrontherapyMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass):
stdFile("Dose.out"),
doseUnit(gray)
{
// Number of the voxels of the phantom
// For Y = Z = 1 the phantom is divided in slices (and not in voxels)
@@ -155,7 +155,7 @@ void HadrontherapyMatrix::Initialize()
/////////////////////////////////////////////////////////////////////////////
// Print generated nuclides list
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyMatrix::PrintNuclides()
{
for (size_t i=0; i<ionStore.size(); i++)
@@ -187,7 +187,6 @@ G4int* HadrontherapyMatrix::GetHitTrack(G4int i, G4int j, G4int k)
// If fluence parameter is true (default value is FALSE) then fluence at voxel (i, j, k) is increased.
// The energyDeposit parameter fill the dose matrix for voxel (i,j,k)
/////////////////////////////////////////////////////////////////////////////
G4bool HadrontherapyMatrix::Fill(G4int trackID,
G4ParticleDefinition* particleDef,
G4int i, G4int j, G4int k,
@@ -273,8 +272,6 @@ G4bool HadrontherapyMatrix::Fill(G4int trackID,
////////////////////////////////////////////////////////////////////////////
//
// General method to store matrix data to filename
void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize)
{
if (data)
@@ -311,6 +308,7 @@ void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize)
}
}
/////////////////////////////////////////////////////////////////////////////
// Store fluence per single ion in multiple files
void HadrontherapyMatrix::StoreFluenceData()
{
@@ -318,6 +316,8 @@ void HadrontherapyMatrix::StoreFluenceData()
StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int));
}
}
/////////////////////////////////////////////////////////////////////////////
// Store dose per single ion in multiple files
void HadrontherapyMatrix::StoreDoseData()
{
@@ -328,16 +328,13 @@ void HadrontherapyMatrix::StoreDoseData()
}
/////////////////////////////////////////////////////////////////////////
// Store dose for all ions into a single file and into ntuples.
// Please note that this function is called via messenger commands
////////////////////////////////////////////////////////////////////////
// Store dose into a single file
// or in histograms. Please note that this function is called via
// messenger commands
// defined in the HadrontherapyAnalysisFileMessenger.cc class file
void HadrontherapyMatrix::StoreDoseFluenceAscii(G4String file)
{
#define width 15L
filename = (file=="") ? stdFile:file;
@@ -373,50 +370,22 @@ void HadrontherapyMatrix::StoreDoseFluenceAscii(G4String file)
ofs << G4endl;
}
G4AnalysisManager* Analysis = G4AnalysisManager::Instance();
Analysis ->SetVerboseLevel(1);
Analysis ->SetFirstHistoId(1);
Analysis ->SetFirstNtupleId(1);
Analysis ->OpenFile("Dose");
Analysis ->CreateNtuple("coordinate", "dose");
Analysis ->CreateNtupleIColumn("i");//1
Analysis ->CreateNtupleIColumn("j");//2
Analysis ->CreateNtupleIColumn("k");//3
Analysis ->CreateNtupleDColumn("totaldose");//6
Analysis ->CreateNtupleIColumn("A");//4
Analysis ->CreateNtupleIColumn("Z");//5
Analysis ->CreateNtupleDColumn("Iondose");//6
Analysis ->CreateNtupleDColumn("fluence");//7
Analysis ->FinishNtuple();
// Write data
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
G4int n = Index(i, j, k);
// Write only not identically null data lines
Analysis->FillNtupleIColumn(1,0, i);
Analysis->FillNtupleIColumn(1,1, j);
Analysis->FillNtupleIColumn(1,2, k);
if (matrix[n])
{
ofs << G4endl;
ofs << i << '\t' << j << '\t' << k << '\t';
// Total dose
ofs << std::setw(width) << (matrix[n]/massOfVoxel)/doseUnit;
Analysis->FillNtupleDColumn(1,3, (matrix[n]/massOfVoxel)/doseUnit);
if (secondary)
{
for (size_t l=0; l < ionStore.size(); l++)
@@ -425,30 +394,18 @@ void HadrontherapyMatrix::StoreDoseFluenceAscii(G4String file)
ofs << std::setw(width) << ionStore[l].dose[n]/massOfVoxel/doseUnit <<
std::setw(width) << ionStore[l].fluence[n];
Analysis->FillNtupleIColumn(1,4, ionStore[l].A);
Analysis->FillNtupleIColumn(1,5, ionStore[l].Z);
Analysis->FillNtupleDColumn(1,6, ionStore[l].dose[n]/massOfVoxel/doseUnit);
Analysis->FillNtupleDColumn(1,7, ionStore[l].fluence[n]);
Analysis->AddNtupleRow(1);
}
}
}
}
ofs.close();
Analysis->Write();
Analysis->CloseFile();
}
}
void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k,
//////////////////////////////////////////////////////////////////////////////
void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k,
G4double energyDeposit)
{
if (matrix)
@@ -61,7 +61,7 @@ HadrontherapyModulator::HadrontherapyModulator(): physiMotherMod(0),
solidMod2(0), logicMod2(0), physiMod2(0),
solidMod3(0), logicMod3(0), physiMod3(0),
solidMod4(0), logicMod4(0), physiMod4(0),
FileName("Modulators/Modulator009_02.txt")
FileName("Modulators/Modulator010.txt")
{
pi=4*atan(1.);
StepNumbers=22;
@@ -28,7 +28,7 @@
//
//
// ****** SUGGESTED PHYSICS FOR ACCURATE SIMULATIONS *********
// ****** IN MEDICAL PHYSICS APPLI CATIONS *********
// ****** IN MEDICAL PHYSICS APPLICATIONS *********
//
// 'HADRONTHERAPY_1' and 'HADRONTHERAPY_2' are both suggested;
// It can be activated inside any macro file using the command:
@@ -65,6 +65,7 @@
#include "G4ParallelWorldPhysics.hh"
#include "G4EmLivermorePhysics.hh"
#include "G4AutoDelete.hh"
#include "G4HadronPhysicsQGSP_BIC_AllHP.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyPhysicsList::HadrontherapyPhysicsList() : G4VModularPhysicsList()
@@ -75,7 +76,7 @@ HadrontherapyPhysicsList::HadrontherapyPhysicsList() : G4VModularPhysicsList()
cutForElectron = defaultCutValue;
cutForPositron = defaultCutValue;
pMessenger = new HadrontherapyPhysicsListMessenger(this);
pMessenger = new HadrontherapyPhysicsListMessenger(this);
SetVerboseLevel(1);
decay_List = new G4DecayPhysics();
// Elecromagnetic physics
@@ -102,7 +103,7 @@ HadrontherapyPhysicsList::~HadrontherapyPhysicsList()
void HadrontherapyPhysicsList::ConstructParticle()
{
decay_List -> ConstructParticle();
}
/////////////////////////////////////////////////////////////////////////////
@@ -114,7 +115,7 @@ void HadrontherapyPhysicsList::ConstructProcess()
decay_List -> ConstructProcess();
emPhysicsList -> ConstructProcess();
//em_config.AddModels();
@@ -57,14 +57,14 @@ HadrontherapyPrimaryGeneratorAction::HadrontherapyPrimaryGeneratorAction()
PrimaryGeneratorMessenger = new HadrontherapyPrimaryGeneratorMessenger(this);
SetDefaultPrimaryParticle();
particleGun = new G4GeneralParticleSource();
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyPrimaryGeneratorAction::~HadrontherapyPrimaryGeneratorAction()
{
delete PrimaryGeneratorMessenger;
delete particleGun;
delete PrimaryGeneratorMessenger;
delete particleGun;
}
/////////////////////////////////////////////////////////////////////////////
@@ -76,8 +76,67 @@ void HadrontherapyPrimaryGeneratorAction::SetDefaultPrimaryParticle()
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
particleGun->GeneratePrimaryVertex(anEvent);
if(NewSource==true)
{
std::ifstream in(calculatedPhaseSpaceFileIN);
G4double e, xpos, ypos, zpos,dirx,diry,dirz;
G4int PDG;
G4ThreeVector pos,dir;
if(in.eof())
{
G4Exception("HadrontherapyPrimaryGeneratorAction", "NoParticles", FatalException, "No more particles in the file");
}
while(!in.eof())
{
in >> e >> xpos >> ypos >>zpos >>dirx>>diry>>dirz >> PDG;
dir= G4ThreeVector(dirx,diry,dirz);
particleGun->GetCurrentSource()->GetEneDist()->SetMonoEnergy(e);
particleGun->GetCurrentSource()->GetParticlePosition().setX(xpos);
particleGun->GetCurrentSource()->GetParticlePosition().setY(ypos);
particleGun->GetCurrentSource()->GetParticlePosition().setZ(zpos);
particleGun->GetCurrentSource()->GetAngDist()->SetParticleMomentumDirection(dir);
G4ParticleDefinition* particleDef = nullptr;
if (PDG > 1000000000)
{
int a=(PDG-1000000000)-(((PDG-1000000000)/10)*10);
if(a>0)
{
PDG=PDG-a;
particleDef = G4IonTable::GetIonTable()->GetIon(PDG);
G4String Nome = particleDef->GetParticleName();
}
else
{
particleDef = G4IonTable::GetIonTable()->GetIon(PDG);
G4String Nome = particleDef->GetParticleName();
}
}
else
{
particleDef = G4ParticleTable::GetParticleTable()->FindParticle(PDG);
}
particleGun->GetCurrentSource()->SetParticleDefinition(particleDef);
particleGun->GeneratePrimaryVertex(anEvent);
}
in.close();
}
else
{
particleGun->GeneratePrimaryVertex(anEvent);
}
}
@@ -37,15 +37,54 @@
#include "G4UIcmdWithABool.hh"
HadrontherapyPrimaryGeneratorMessenger::HadrontherapyPrimaryGeneratorMessenger(
HadrontherapyPrimaryGeneratorAction* HadrontherapyGun)
HadrontherapyPrimaryGeneratorAction* HadrontherapyGun)
:HadrontherapyAction(HadrontherapyGun)
{
changeTheSource = new G4UIdirectory("/primaryParticleData/");
changeTheSource -> SetGuidance("Command to change the source");
NewSource = new G4UIcmdWithABool("/primaryParticleData/NewSource",this);
NewSource -> SetParameterName("NewSource ", true);
NewSource -> SetDefaultValue("false");
NewSource -> SetGuidance("Set if you want read a .txt file"
"\n[usage]: /primaryParticleData/NewSource [true/false]");
NewSource -> AvailableForStates(G4State_Idle, G4State_PreInit);
calculatedPhaseSpaceFileIN=new G4UIcmdWithAString("/primaryParticleData/calculatedPhaseSpaceFileIN",this);
calculatedPhaseSpaceFileIN->SetDefaultValue("");
calculatedPhaseSpaceFileIN->SetGuidance("full path and file name of the phase space file to be used as particle generator");
}
HadrontherapyPrimaryGeneratorMessenger::~HadrontherapyPrimaryGeneratorMessenger()
{
delete NewSource;
delete changeTheSource;
delete calculatedPhaseSpaceFileIN;
}
void HadrontherapyPrimaryGeneratorMessenger::SetNewValue(G4UIcommand* command, G4String NewValue)
{
if (command == calculatedPhaseSpaceFileIN)
{
HadrontherapyAction->setCalculatedPhaseSpaceFileIN(NewValue);
}
if (command == NewSource)
{
HadrontherapyAction->setNewSource(NewSource->GetNewBoolValue(NewValue));
}
}
+811
View File
@@ -0,0 +1,811 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "HadrontherapyRBE.hh"
#include "HadrontherapyMatrix.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4GenericMessenger.hh"
#include "G4Pow.hh"
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <sstream>
#include <numeric>
#define width 15L
using namespace std;
// TODO: Perhaps we can use the material database???
const std::map<G4String, G4int> elements = {
{"H", 1},
{"He", 2},
{"Li", 3},
{"Be", 4},
{"B", 5},
{"C", 6},
{"N", 7},
{"O", 8},
{"F", 9},
{"Ne", 10}
};
HadrontherapyRBE* HadrontherapyRBE::instance = nullptr;
HadrontherapyRBE* HadrontherapyRBE::GetInstance()
{
return instance;
}
HadrontherapyRBE* HadrontherapyRBE::CreateInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double massOfVoxel)
{
if (instance) delete instance;
instance = new HadrontherapyRBE(voxelX, voxelY, voxelZ, massOfVoxel);
return instance;
}
HadrontherapyRBE::HadrontherapyRBE(G4int voxelX, G4int voxelY, G4int voxelZ, G4double massOfVoxel)
: fNumberOfVoxelsAlongX(voxelX),
fNumberOfVoxelsAlongY(voxelY),
fNumberOfVoxelsAlongZ(voxelZ),
fNumberOfVoxels(voxelX * voxelY * voxelY),
fMassOfVoxel(massOfVoxel)
{
CreateMessenger();
// x axis for 1-D plot
// TODO: Remove
x = new G4double[fNumberOfVoxelsAlongX];
for (G4int i = 0; i < fNumberOfVoxelsAlongX; i++)
{
x[i] = 0;
}
}
HadrontherapyRBE::~HadrontherapyRBE()
{
delete[] x;
delete fMessenger;
}
void HadrontherapyRBE::PrintParameters()
{
G4cout << "RBE Cell line: " << fActiveCellLine << G4endl;
G4cout << "RBE Dose threshold value: " << fDoseCut / gray << " gray" << G4endl;
G4cout << "RBE Alpha X value: " << fAlphaX * gray << " 1/gray" << G4endl;
G4cout << "RBE Beta X value: " << fBetaX * pow(gray, 2.0) << " 1/gray2" << G4endl;
}
/**
* @short Split string into parts using a delimiter.
*
* @param line a string to be splitted
* @param delimiter a string to be looked for
*
* Usage: Help function for reading CSV
* Also remove spaces and quotes around.
* Note: If delimiter is inside a string, the function fails!
*/
vector<G4String> split(const G4String& line, const G4String& delimiter)
{
vector<G4String> result;
size_t current = 0;
size_t pos = 0;
while(pos != G4String::npos)
{
pos = line.find(delimiter, current);
G4String token = line.substr(current, pos - current);
token = token.strip(G4String::both);
token = token.strip(G4String::both, '\"');
result.push_back(token);
current = pos + delimiter.size();
}
return result;
}
void HadrontherapyRBE::LoadLEMTable(G4String path)
{
// TODO: Check for presence? Perhaps we want to be able to load more
ifstream in(path);
if (!in)
{
stringstream ss;
ss << "Cannot open LEM table input file: " << path;
G4Exception("HadrontherapyRBE::LoadData", "WrongTable", FatalException, ss.str().c_str());
}
// Start with the first line
G4String line;
if (!getline(in, line))
{
stringstream ss;
ss << "Cannot read header from the LEM table file: " << path;
G4Exception("HadrontherapyRBE::LoadLEMTable", "CannotReadHeader", FatalException, ss.str().c_str());
}
vector<G4String> header = split(line, ",");
// Find the order of columns
std::vector<G4String> columns = { "alpha_x", "beta_x", "D_t", "specific_energy", "alpha", "beta", "cell", "particle"};
std::map<G4String, int> columnIndices;
for (auto columnName : columns)
{
auto pos = find(header.begin(), header.end(), columnName);
if (pos == header.end())
{
stringstream ss;
ss << "Column " << columnName << " not present in the LEM table file.";
G4Exception("HadrontherapyRBE::LoadLEMTable", "ColumnNotPresent", FatalException, ss.str().c_str());
}
else
{
columnIndices[columnName] = distance(header.begin(), pos);
}
}
// Continue line by line
while (getline(in, line))
{
vector<G4String> lineParts = split(line, ",");
G4String cellLine = lineParts[columnIndices["cell"]];
G4int element = elements.at(lineParts[columnIndices["particle"]]);
fTablesEnergy[cellLine][element].push_back(
stod(lineParts[columnIndices["specific_energy"]]) * MeV
);
fTablesAlpha[cellLine][element].push_back(
stod(lineParts[columnIndices["alpha"]])
);
/* fTablesLet[cellLine][element].push_back(
stod(lineParts[columnIndices["let"]])
); */
fTablesBeta[cellLine][element].push_back(
stod(lineParts[columnIndices["beta"]])
);
fTablesAlphaX[cellLine] = stod(lineParts[columnIndices["alpha_x"]]) / gray;
fTablesBetaX[cellLine] = stod(lineParts[columnIndices["beta_x"]]) / (gray * gray);
fTablesDoseCut[cellLine] = stod(lineParts[columnIndices["D_t"]]) * gray;
}
// Sort the tables by energy
// (https://stackoverflow.com/a/12399290/2692780)
for (auto aPair : fTablesEnergy)
{
for (auto ePair : aPair.second)
{
vector<G4double>& tableEnergy = fTablesEnergy[aPair.first][ePair.first];
vector<G4double>& tableAlpha = fTablesAlpha[aPair.first][ePair.first];
vector<G4double>& tableBeta = fTablesBeta[aPair.first][ePair.first];
vector<size_t> idx(tableEnergy.size());
iota(idx.begin(), idx.end(), 0);
sort(idx.begin(), idx.end(),
[&tableEnergy](size_t i1, size_t i2) {return tableEnergy[i1] < tableEnergy[i2];});
vector<vector<G4double>*> tables = {
&tableEnergy, &tableAlpha, &tableBeta
};
for (vector<G4double>* table : tables)
{
vector<G4double> copy = *table;
for (size_t i = 0; i < copy.size(); ++i)
{
(*table)[i] = copy[idx[i]];
}
// G4cout << (*table)[0];
// reorder(*table, idx);
G4cout << (*table)[0] << G4endl;
}
}
}
if (fVerboseLevel > 0)
{
G4cout << "RBE: read LEM data for the following cell lines and elements [number of points]: " << G4endl;
for (auto aPair : fTablesEnergy)
{
G4cout << "- " << aPair.first << ": ";
for (auto ePair : aPair.second)
{
G4cout << ePair.first << "[" << ePair.second.size() << "] ";
}
G4cout << G4endl;
}
}
}
void HadrontherapyRBE::SetCellLine(G4String name)
{
if (fTablesEnergy.size() == 0)
{
G4Exception("HadrontherapyRBE::SetCellLine", "NoCellLine", FatalException, "Cannot select cell line, probably LEM table not loaded yet?");
}
if (fTablesEnergy.find(name) == fTablesEnergy.end())
{
stringstream str;
str << "Cell line " << name << " not found in the LEM table.";
G4Exception("HadrontherapyRBE::SetCellLine", "", FatalException, str.str().c_str());
}
else
{
fAlphaX = fTablesAlphaX[name];
fBetaX = fTablesBetaX[name];
fDoseCut = fTablesDoseCut[name];
fActiveTableEnergy = &fTablesEnergy[name];
fActiveTableAlpha = &fTablesAlpha[name];
fActiveTableBeta = &fTablesBeta[name];
fMinZ = 0;
fMaxZ = 0;
fMinEnergies.clear();
fMaxEnergies.clear();
for (auto energyPair : *fActiveTableEnergy)
{
if (!fMinZ || (energyPair.first < fMinZ)) fMinZ = energyPair.first;
if (energyPair.first > fMaxZ) fMaxZ = energyPair.first;
fMinEnergies[energyPair.first] = energyPair.second[0];
fMaxEnergies[energyPair.first] = energyPair.second[energyPair.second.size() - 1];
}
}
fActiveCellLine = name;
if (fVerboseLevel > 0)
{
G4cout << "RBE: cell line " << name << " selected." << G4endl;
}
}
std::tuple<G4double, G4double> HadrontherapyRBE::GetHitAlphaAndBeta(G4double E, G4int Z)
{
if (!fActiveTableEnergy)
{
G4Exception("HadrontherapyRBE::GetHitAlphaAndBeta", "NoCellLine", FatalException, "No cell line selected. Please, do it using the /rbe/cellLine command.");
}
// Check we are in the tables
if ((Z < fMinZ) || (Z > fMaxZ))
{
if (fVerboseLevel > 1)
{
stringstream str;
str << "Alpha & beta calculation supported only for ";
str << fMinZ << " <= Z <= " << fMaxZ << ", but " << Z << " requested.";
G4Exception("HadrontherapyRBE::GetHitAlphaAndBeta", "", JustWarning, str.str().c_str());
}
return make_tuple<G4double, G4double>( 0.0, 0.0 ); //out of table!
}
if ((E < fMinEnergies[Z]) || (E >= fMaxEnergies[Z]))
{
if (fVerboseLevel > 2)
{
G4cout << "RBE hit: Z=" << Z << ", E=" << E << " => out of LEM table";
if (fVerboseLevel > 3)
{
G4cout << " (" << fMinEnergies[Z] << " to " << fMaxEnergies[Z] << " MeV)";
}
G4cout << G4endl;
}
return make_tuple<G4double, G4double>( 0.0, 0.0 ); //out of table!
}
std::vector<G4double>& vecEnergy = (*fActiveTableEnergy)[Z];
std::vector<G4double>& vecAlpha = (*fActiveTableAlpha)[Z];
std::vector<G4double>& vecBeta = (*fActiveTableBeta)[Z];
// Find the row in energy tables
const auto eLarger = upper_bound(begin(vecEnergy), end(vecEnergy), E);
const G4int lower = distance(begin(vecEnergy), eLarger) - 1;
const G4int upper = lower + 1;
// Interpolation
const G4double energyLower = vecEnergy[lower];
const G4double energyUpper = vecEnergy[upper];
const G4double energyFraction = (E - energyLower) / (energyUpper - energyLower);
//linear interpolation along E
const G4double alpha = ((1 - energyFraction) * vecAlpha[lower] + energyFraction * vecAlpha[upper]);
const G4double beta = ((1 - energyFraction) * vecBeta[lower] + energyFraction * vecBeta[upper]);
if (fVerboseLevel > 2)
{
G4cout << "RBE hit: Z=" << Z << ", E=" << E << " => alpha=" << alpha << ", beta=" << beta << G4endl;
}
return make_tuple(alpha, beta);
}
// Zaider & Rossi alpha & Beta mean
void HadrontherapyRBE::ComputeAlphaAndBeta()
{
if (fVerboseLevel > 0)
{
G4cout << "RBE: Computing alpha and beta..." << G4endl;
}
fAlpha = fAlphaNumerator / (fDenominator * gray);
fBeta = pow(fBetaNumerator / fDenominator * gray, 2.0);
//g4pow -> powN(fBetaNumerator / fDenominator * gray, 2)
}
void HadrontherapyRBE::ComputeRBE()
{
if (fVerboseLevel > 0)
{
G4cout << "RBE: Computing survival and RBE..." << G4endl;
}
G4double smax = fAlphaX + 2 * fBetaX * fDoseCut;
// Prepare matrices that were not initialized yet
fLnS.resize(fNumberOfVoxels);
fDoseX.resize(fNumberOfVoxels);
for (G4int i = 0; i < fNumberOfVoxels; i++)
{
if (std::isnan(fAlpha[i]) || std::isnan(fBeta[i]))
{
fLnS[i] = 0.0;
fDoseX[i] = 0.0;
}
else if (fDose[i] <= fDoseCut)
{
fLnS[i] = -(fAlpha[i] * fDose[i]) - (fBeta[i] * (pow(fDose[i], 2.0))) ;
fDoseX[i] = sqrt((-fLnS[i] / fBetaX) + pow((fAlphaX / (2 * fBetaX)), 2.0)) - (fAlphaX / (2 * fBetaX));
}
else
{
G4double ln_Scut = -(fAlpha[i] * fDoseCut) - (fBeta[i] * (pow((fDoseCut), 2.0)));
fLnS[i] = ln_Scut - ((fDose[i] - fDoseCut) * smax);
// TODO: CHECK THIS!!!
fDoseX[i] = ( (-fLnS[i] + ln_Scut) / smax ) + fDoseCut;
}
}
fRBE = fDoseX / fDose;
fSurvival = exp(fLnS);
}
void HadrontherapyRBE::SetDenominator(const HadrontherapyRBE::array_type denom)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Setting denominator..." << G4endl;
}
fDenominator = denom;
}
void HadrontherapyRBE::AddDenominator(const HadrontherapyRBE::array_type denom)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Adding denominator...";
}
if (fDenominator.size())
{
fDenominator += denom;
}
else
{
if (fVerboseLevel > 1)
{
G4cout << " (created empty array)";
}
fDenominator = denom;
}
G4cout << G4endl;
}
void HadrontherapyRBE::SetAlphaNumerator(const HadrontherapyRBE::array_type alpha)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Setting alpha numerator..." << G4endl;
}
fAlphaNumerator = alpha;
}
void HadrontherapyRBE::SetBetaNumerator(const HadrontherapyRBE::array_type beta)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Setting beta numerator..." << G4endl;
}
fBetaNumerator = beta;
}
void HadrontherapyRBE::AddAlphaNumerator(const HadrontherapyRBE::array_type alpha)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Adding alpha numerator...";
}
if (fAlphaNumerator.size())
{
fAlphaNumerator += alpha;
}
else
{
if (fVerboseLevel > 1)
{
G4cout << " (created empty array)";
}
fAlphaNumerator = alpha;
}
G4cout << G4endl;
}
void HadrontherapyRBE::AddBetaNumerator(const HadrontherapyRBE::array_type beta)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Adding beta...";
}
if (fBetaNumerator.size())
{
fBetaNumerator += beta;
}
else
{
if (fVerboseLevel > 1)
{
G4cout << " (created empty array)";
}
fBetaNumerator = beta;
}
G4cout << G4endl;
}
void HadrontherapyRBE::SetEnergyDeposit(const std::valarray<G4double> eDep)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Setting dose..." << G4endl;
}
fDose = eDep * (fDoseScale / fMassOfVoxel);
}
void HadrontherapyRBE::AddEnergyDeposit(const std::valarray<G4double> eDep)
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Adding dose... (" << eDep.size() << " points)" << G4endl;
}
if (fDose.size())
{
fDose += eDep * (fDoseScale / fMassOfVoxel);
}
else
{
if (fVerboseLevel > 1)
{
G4cout << " (created empty array)";
}
fDose = eDep * (fDoseScale / fMassOfVoxel);
}
}
void HadrontherapyRBE::StoreAlphaAndBeta()
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Writing alpha and beta..." << G4endl;
}
ofstream ofs(fAlphaBetaPath);
ComputeAlphaAndBeta();
if (ofs.is_open())
{
ofs << "alpha" << std::setw(width) << "beta " << std::setw(width) << "depth(slice)" << G4endl;
for (G4int i = 0; i < fNumberOfVoxelsAlongX * fNumberOfVoxelsAlongY * fNumberOfVoxelsAlongZ; i++)
ofs << fAlpha[i]*gray << std::setw(15L) << fBeta[i]*pow(gray, 2.0) << std::setw(15L) << i << G4endl;
}
if (fVerboseLevel > 0)
{
G4cout << "RBE: Alpha and beta written to " << fAlphaBetaPath << G4endl;
}
}
void HadrontherapyRBE::StoreRBE()
{
ofstream ofs(fRBEPath);
// TODO: only if not yet calculated. Or in RunAction???
ComputeRBE();
if (ofs.is_open())
{
ofs << "Dose(Gy)" << std::setw(width) << "ln(S) " << std::setw(width) << "Survival" << std::setw(width) << "DoseB(Gy)" << std::setw(width) << "RBE" << std::setw(width) << "depth(slice)" << G4endl;
for (G4int i = 0; i < fNumberOfVoxelsAlongX * fNumberOfVoxelsAlongY * fNumberOfVoxelsAlongZ; i++)
ofs << (fDose[i] / gray) << std::setw(width) << fLnS[i] << std::setw(width) << fSurvival[i]
<< std::setw(width) << fDoseX[i] / gray << std::setw(width) << fRBE[i] << std::setw(width) << i << G4endl;
}
if (fVerboseLevel > 0)
{
G4cout << "RBE: RBE written to " << fRBEPath << G4endl;
}
}
void HadrontherapyRBE::Reset()
{
if (fVerboseLevel > 1)
{
G4cout << "RBE: Reset(): ";
}
fAlphaNumerator = 0.0;
fBetaNumerator = 0.0;
fDenominator = 0.0;
fDose = 0.0;
if (fVerboseLevel > 1)
{
G4cout << fAlphaNumerator.size() << " points." << G4endl;
}
}
void HadrontherapyRBE::CreateMessenger()
{
fMessenger = new G4GenericMessenger(this, "/rbe/");
fMessenger->SetGuidance("RBE calculation");
fMessenger->DeclareMethod("calculation", &HadrontherapyRBE::SetCalculationEnabled)
.SetGuidance("Whether to enable RBE calculation")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("verbose", &HadrontherapyRBE::SetVerboseLevel)
.SetGuidance("Set verbosity level of RBE")
.SetGuidance("0 = quiet")
.SetGuidance("1 = important messages (~10 per run)")
.SetGuidance("2 = debug")
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("loadLemTable", &HadrontherapyRBE::LoadLEMTable)
.SetGuidance("Load a LEM table used in calculating alpha&beta")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("cellLine", &HadrontherapyRBE::SetCellLine)
.SetGuidance("Set the cell line for alpha&beta calculation")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("doseScale", &HadrontherapyRBE::SetDoseScale)
.SetGuidance("Set the scaling factor to calculate RBE with the real physical dose")
.SetGuidance("If you don't set this, the RBE will be incorrect")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("accumulate", &HadrontherapyRBE::SetAccumulationEnabled)
.SetGuidance("If false, reset the values at the beginning of each run.")
.SetGuidance("If true, all runs are summed together")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
fMessenger->DeclareMethod("reset", &HadrontherapyRBE::Reset)
.SetGuidance("Reset accumulated data (relevant only if accumulate mode is on)")
.SetStates(G4State_PreInit, G4State_Idle)
.SetToBeBroadcasted(false);
}
/*
G4bool HadrontherapyRBE::LinearLookup(G4double E, G4double LET, G4int Z)
{
G4int j;
G4int indexE;
if ( E < vecEnergy[0] || E >= vecEnergy[GetRowVecEnergy() - 1]) return false; //out of table!
// Search E
for (j = 0; j < GetRowVecEnergy(); j++)
{
if (j + 1 == GetRowVecEnergy()) break;
if (E >= vecEnergy[j] && E < vecEnergy[j + 1]) break;
}
indexE = j;
G4int k = (indexE * column);
G4int l = ((indexE + 1) * column);
if (Z <= 8) //linear interpolation along E for calculate alpha and beta
{
interpolation_onE(k, l, indexE, E, Z);
}
else
{
return interpolation_onLET1_onLET2_onE(k, l, indexE, E, LET);
}
return true;
}
*/
/*
void HadrontherapyRBE::interpolation_onE(G4int k, G4int l, G4int indexE, G4double E, G4int Z)
{
// k=(indexE*column) identifies the position of E1 known the value of E (identifies the group of 8 elements in the array at position E1)
// Z-1 identifies the vector ion position relative to the group of 8 values found
k = k + (Z - 1);
l = l + (Z - 1);
//linear interpolation along E
alpha = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecAlpha[k]) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecAlpha[l];
beta = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecBeta[k]) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecBeta[l];
}
G4bool HadrontherapyRBE::interpolation_onLET1_onLET2_onE(G4int k, G4int l, G4int indexE, G4double E, G4double LET)
{
G4double LET1_2, LET3_4, LET1_2_beta, LET3_4_beta;
G4int indexLET1, indexLET2, indexLET3, indexLET4;
size_t i;
if ( (LET >= vecLET[k + column - 1] && LET >= vecLET[l + column - 1]) || (LET < vecLET[k] && LET < vecLET[l]) ) return false; //out of table!
//Find the value of E1 is detected the value of LET among the 8 possible values corresponding to E1
for (i = 0; i < column - 1; i++)
{
if ( (i + 1 == column - 1) || (LET < vecLET[k]) ) break;
else if (LET >= vecLET[k] && LET < vecLET[k + 1]) break;
k++;
}
indexLET1 = k;
indexLET2 = k + 1;
//Find the value of E2 is detected the value of LET among the 8 possible values corresponding to E2
for (i = 0; i < column - 1; i++)
{
if (i + 1 == column - 1) break;
if (LET >= vecLET[l] && LET < vecLET[l + 1]) break; // time to interpolate
l++;
}
indexLET3 = l;
indexLET4 = l + 1;
//Interpolation between LET1 and LET2 on E2 position
LET1_2 = (((vecLET[indexLET2] - LET) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecAlpha[indexLET1]) + ((LET - vecLET[indexLET1]) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecAlpha[indexLET2];
LET1_2_beta = (((vecLET[indexLET2] - LET) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecBeta[indexLET1]) + ((LET - vecLET[indexLET1]) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecBeta[indexLET2];
//Interpolation between LET3 and LET4 on E2 position
LET3_4 = (((vecLET[indexLET4] - LET) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecAlpha[indexLET3]) + ((LET - vecLET[indexLET3]) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecAlpha[indexLET4];
LET3_4_beta = (((vecLET[indexLET4] - LET) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecBeta[indexLET3]) + ((LET - vecLET[indexLET3]) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecBeta[indexLET4];
//Interpolation along E between LET1_2 and LET3_4
alpha = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET1_2) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET3_4;
beta = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET1_2_beta) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET3_4_beta;
return true;
}
**/
/* void HadrontherapyRBE::SetThresholdValue(G4double dosecut)
{
fDoseCut = dosecut;
}
void HadrontherapyRBE::SetAlphaX(G4double alphaX)
{
fAlphaX = alphaX;
}
void HadrontherapyRBE::SetBetaX(G4double betaX)
{
fBetaX = betaX;
}*/
void HadrontherapyRBE::SetCalculationEnabled(G4bool enabled)
{
fCalculationEnabled = enabled;
}
void HadrontherapyRBE::SetAccumulationEnabled(G4bool accumulate)
{
fAccumulate = accumulate;
// The accumulation should start now, not taking into account old data
Reset();
}
/*
void HadrontherapyRBE::SetLEMTablePath(G4String path)
{
// fLEMTablePath = path;
LoadLEMTable(path);
}
*/
void HadrontherapyRBE::SetDoseScale(G4double scale)
{
fDoseScale = scale;
}
// Nearest neighbor interpolation
/*
G4bool HadrontherapyRBE::NearLookup(G4double E, G4double DE)
{
size_t j = 0, step = 77;
// Check bounds
if (E < vecE[0] || E > vecE.back() || DE < vecDE[0] || DE > vecDE[step - 1]) return false; //out of table!
// search for Energy... simple linear search. This take approx 1 us per single search on my sempron 2800+ laptop
for (; j < vecE.size(); j += step)
{
if (E <= vecE[j]) break;
}
if (j == vecE.size()) j -= step;
if (j == vecE.size() && E > vecE[j]) return false; // out of table!
// find nearest (better interpolate)
if ( j > 0 && ((vecE[j] - E) > (E - vecE[j - 1])) ) {j = j - step;}
bestE = vecE[j];
// search for stopping power... simple linear search
for (; vecE[j] == bestE && j < vecE.size(); j++)
{
if (DE <= vecDE[j]) break;
}
if (j == vecE.size() && DE > vecDE[j]) return false;// out of table!
if (j == 0 && (E < vecE[j] || DE < vecDE[j]) ) return false;// out of table!
if ( (vecDE[j] - DE) > (DE - vecDE[j - 1]) ) {j = j - 1;}
bestDE = vecDE[j];
this -> alpha = vecAlpha[j];
this -> beta = vecBeta[j];
return true;
}
*/
@@ -0,0 +1,131 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "HadrontherapyRBEAccumulable.hh"
#include "HadrontherapyRBE.hh"
#include <tuple>
#include <G4SystemOfUnits.hh>
using namespace std;
HadrontherapyRBEAccumulable::HadrontherapyRBEAccumulable()
: G4VAccumulable("RBE")
{
}
void HadrontherapyRBEAccumulable::Merge(const G4VAccumulable& rhs)
{
if (GetVerboseLevel() > 1)
{
G4cout << "HadrontherapyRBEAccumulable::Merge()" << G4endl;
}
const HadrontherapyRBEAccumulable& other = dynamic_cast<const HadrontherapyRBEAccumulable&>(rhs);
fAlphaNumerator += other.fAlphaNumerator;
fDenominator += other.fDenominator;
fBetaNumerator += other.fBetaNumerator;
fEnergyDeposit += other.fEnergyDeposit;
}
void HadrontherapyRBEAccumulable::Reset()
{
if (GetVerboseLevel() > 1)
{
G4cout << "HadrontherapyRBEAccumulable::Reset()" << G4endl;
}
if (fInitialized)
{
fAlphaNumerator = 0.0;
fBetaNumerator = 0.0;
fDenominator = 0.0;
fEnergyDeposit = 0.0;
}
else
{
Initialize();
}
}
void HadrontherapyRBEAccumulable::Accumulate(G4double E, G4double energyDeposit, G4double dX, G4int Z, G4int i, G4int j, G4int k)
{
if (!fInitialized)
{
G4Exception("HadrontherapyRBEAccumulable::Accumulate", "NotInitialized", FatalException, "Accumulable not initialized. Must be a programming error.");
}
if (GetVerboseLevel() > 2)
{
G4cout << "HadrontherapyRBEAccumulable::Accumulate() in " << i << ", " << j << ", " << k << G4endl;
}
if (energyDeposit <= 0)
{
return;
}
size_t n = GetIndex(i, j, k);
fEnergyDeposit[n] += energyDeposit;
if ((Z >= 1) && (dX > 0) && (E > 0)) // TODO: Verify this condition
{
tuple<G4double, G4double> alpha_beta = HadrontherapyRBE::GetInstance()->GetHitAlphaAndBeta(E, Z);
fDenominator[n] += energyDeposit;
fAlphaNumerator[n] += get<0>(alpha_beta) * energyDeposit;
fBetaNumerator[n] += sqrt(get<1>(alpha_beta)) * energyDeposit;
}
}
const HadrontherapyRBEAccumulable::array_type HadrontherapyRBEAccumulable::GetEnergyDeposit() const
{
return fEnergyDeposit;
}
G4int HadrontherapyRBEAccumulable::GetVerboseLevel() const
{
return HadrontherapyRBE::GetInstance()->GetVerboseLevel();
}
void HadrontherapyRBEAccumulable::Initialize()
{
if (GetVerboseLevel() > 1)
{
G4cout << "HadrontherapyRBEAccumulable::Initialize(): ";
}
auto rbe = HadrontherapyRBE::GetInstance();
fVoxelsAlongX = rbe->GetNumberOfVoxelsAlongX();
fVoxelsAlongY = rbe->GetNumberOfVoxelsAlongY();
fVoxelsAlongZ = rbe->GetNumberOfVoxelsAlongZ();
fVoxels = fVoxelsAlongX * fVoxelsAlongY * fVoxelsAlongZ;
if (GetVerboseLevel() > 1)
{
G4cout << fVoxels << " voxels." << G4endl;
}
fAlphaNumerator = array_type(0.0, fVoxels);
fBetaNumerator = array_type(0.0, fVoxels);
fDenominator = array_type(0.0, fVoxels);
fEnergyDeposit = array_type(0.0, fVoxels);
fInitialized = true;
}
@@ -28,6 +28,7 @@
#include "HadrontherapyRunAction.hh"
#include "HadrontherapyEventAction.hh"
#include "HadrontherapyAnalysis.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4UImanager.hh"
@@ -36,48 +37,125 @@
#include "G4SDManager.hh"
#include "G4Timer.hh"
#include "HadrontherapyRunAction.hh"
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyRBE.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
#include <G4AccumulableManager.hh>
/////////////////////////////////////////////////////////////////////////////
HadrontherapyRunAction::HadrontherapyRunAction()
{
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->RegisterAccumulable(&fRBEAccumulable);
// Create analysis manager
// The choice of analysis technology is done via selectin of a namespace
// in Analysis.hh
auto analysisManager =G4AnalysisManager::Instance();
G4cout << "Using " << analysisManager -> GetType() << G4endl;
analysisManager->SetVerboseLevel(1);
analysisManager->SetFirstHistoId(1);
// Comment out the following line to generate an N-tuple
analysisManager-> SetFirstNtupleId(2);
// Creating the histograms of primary kinetic
// energy (Ekin) and of the energy deposited (Edep)
// in the first voxel/slice of the water phantom
analysisManager -> CreateH1("Ekin","Ekin the voxel", 400,20*MeV, 60*MeV);
analysisManager -> CreateH1("Edep","Edep the voxel", 200, -10, 10*MeV);
// Example of how to create an Ntuple (comment-out, if needed)
//analysisManager->CreateNtuple("NYUPLA", "Edep and TrackL");
//analysisManager->CreateNtupleDColumn("Ekin");
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyRunAction::~HadrontherapyRunAction()
{
delete G4AnalysisManager::Instance();
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyRunAction::BeginOfRunAction(const G4Run* aRun)
{
// Get analysis manager
auto analysisManager = G4AnalysisManager::Instance();
// Open an output file
//
G4String fileName = "Hadrontherapy";
analysisManager->OpenFile(fileName);
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Reset();
G4RunManager::GetRunManager()-> SetRandomNumberStore(true);
G4cout << "Run " << aRun -> GetRunID() << " starts ..." << G4endl;
HadrontherapyRBE *rbe = HadrontherapyRBE::GetInstance();
if (rbe->IsCalculationEnabled() && IsMaster() && rbe->GetVerboseLevel() > 0)
{
rbe->PrintParameters();
}
electromagnetic = 0;
hadronic = 0;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyRunAction::EndOfRunAction(const G4Run*)
{
auto analysisManager = G4AnalysisManager::Instance();
//G4cout << " Summary of Run " << aRun -> GetRunID() <<" :"<< G4endl;
//G4cout << "Number of electromagnetic processes of primary particles in the phantom:"
// << electromagnetic << G4endl;
//G4cout << "Number of hadronic processes of primary particles in the phantom:"
// << hadronic << G4endl;
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Merge();
// Tell the RBE class what we have accumulated...
HadrontherapyRBE *rbe = HadrontherapyRBE::GetInstance();
if (rbe->IsCalculationEnabled() && IsMaster())
{
if (rbe->IsAccumulationEnabled())
{
rbe->AddAlphaNumerator(fRBEAccumulable.GetAlphaNumerator());
rbe->AddBetaNumerator(fRBEAccumulable.GetBetaNumerator());
rbe->AddDenominator(fRBEAccumulable.GetDenominator());
rbe->AddEnergyDeposit(fRBEAccumulable.GetEnergyDeposit());
}
else
{
rbe->SetAlphaNumerator(fRBEAccumulable.GetAlphaNumerator());
rbe->SetBetaNumerator(fRBEAccumulable.GetBetaNumerator());
rbe->SetDenominator(fRBEAccumulable.GetDenominator());
rbe->SetEnergyDeposit(fRBEAccumulable.GetEnergyDeposit());
}
rbe->StoreAlphaAndBeta();
rbe->StoreRBE();
}
analysisManager->Write();
analysisManager->CloseFile();
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyRunAction::AddEMProcess()
{
electromagnetic += 1;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyRunAction::AddHadronicProcess()
{
hadronic += 1;
}
@@ -65,11 +65,11 @@ void HadrontherapySteppingAction::UserSteppingAction(const G4Step* aStep)
// G4Track* theTrack = aStep->GetTrack();
//G4StepPoint* PreStep = aStep->GetPreStepPoint();
//G4StepPoint* PostStep = aStep->GetPostStepPoint();
G4StepPoint* PreStep = aStep->GetPreStepPoint();
G4StepPoint* PostStep = aStep->GetPostStepPoint();
//G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
//G4TouchableHandle touchPostStep = PostStep->GetTouchableHandle();
G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
G4TouchableHandle touchPostStep = PostStep->GetTouchableHandle();
//G4double PreStepX =PreStep->GetPosition().x();
//G4double PreStepY =PreStep->GetPosition().y();
@@ -79,14 +79,12 @@ void HadrontherapySteppingAction::UserSteppingAction(const G4Step* aStep)
//G4double PostStepY =PostStep->GetPosition().y();
//G4double PostStepZ =PostStep->GetPosition().z();
//To get the current volume:
//G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
//G4VPhysicalVolume* volumePost =touchPostStep->GetVolume();
//To get its name:
//G4String namePre = volumePre->GetName();
G4String namePre = volumePre->GetName();
// positions in the global coordinate system:
@@ -98,27 +96,56 @@ void HadrontherapySteppingAction::UserSteppingAction(const G4Step* aStep)
//G4double parentID =aStep->GetTrack()->GetParentID();
//G4double trackID =aStep->GetTrack()->GetTrackID();
//G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
//G4double PosX = aStep->GetTrack()->GetPosition().x();
//G4double PosY = aStep->GetTrack()->GetPosition().y();
//G4double PosZ = aStep->GetTrack()->GetPosition().z();
G4double PosX = aStep->GetTrack()->GetPosition().x();
G4double PosY = aStep->GetTrack()->GetPosition().y();
G4double PosZ = aStep->GetTrack()->GetPosition().z();
G4String volume= aStep->GetTrack()->GetVolume()->GetName();
G4Track* theTrack = aStep->GetTrack();
//G4String material= aStep -> GetTrack() -> GetMaterial() -> GetName();
//G4cout << "material " << material << G4endl;
//G4String volume= aStep->GetTrack()->GetVolume()->GetName();
//G4String pvname= pv-> GetName();
G4String particleName = aStep->GetTrack()->GetDefinition()->GetParticleName();
G4double momentumX = aStep->GetTrack()->GetMomentumDirection().x();
G4double momentumY = aStep->GetTrack()->GetMomentumDirection().y();
G4double momentumZ = aStep->GetTrack()->GetMomentumDirection().z();
G4ParticleDefinition *particleDef = theTrack -> GetDefinition();
G4int pdg = particleDef ->GetPDGEncoding();
if(namePre == "VirtualLayer")
{
std::ofstream WriteDataIn("Virtual_Layer.txt", std::ios::app);
WriteDataIn
<< eKin <<" " // 1
<< PosX <<" " // 2
<< PosY <<" " // 3
<< PosZ <<" " // 4
<< momentumX <<" " // 5
<< momentumY <<" " // 6
<< momentumZ <<" " // 7
<< pdg
//<< theTrack << '\t' << " "
<< G4endl;
theTrack -> SetTrackStatus(fKillTrackAndSecondaries);
}
}
@@ -43,8 +43,8 @@
#include "G4NistManager.hh"
#include "G4NistElementBuilder.hh"
#include "HadrontherapyDetectorConstruction.hh"
#include "TrentoPassiveProtonBeamLine.hh"
#include "TrentoPassiveProtonBeamLineMessenger.hh"
#include "HadrontherapyTIFPAPassiveProtonBeamLine.hh"
#include "HadrontherapyTIFPAPassiveProtonBeamLineMessenger.hh"
/////////////////////////////////////////////////////////////////////////////
TrentoPassiveProtonBeamLine::TrentoPassiveProtonBeamLine():
@@ -27,8 +27,8 @@
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
#include "TrentoPassiveProtonBeamLine.hh"
#include "TrentoPassiveProtonBeamLineMessenger.hh"
#include "HadrontherapyTIFPAPassiveProtonBeamLine.hh"
#include "HadrontherapyTIFPAPassiveProtonBeamLineMessenger.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
File diff suppressed because it is too large Load Diff
@@ -210,7 +210,7 @@ void PassiveCarbonBeamLine::SetDefaultDimensions()
kaptonWindowMaterial = kaptonNist;
// Material of ripple filter
rippleFilterMaterial = PMMANist;
rippleFilterMaterial = airNist;
rippleFilterBoxMaterial = airNist;
// Materials of the monitor chamber
@@ -386,7 +386,7 @@ void PassiveCarbonBeamLine::VacuumToAirInterface()
// --------------------------//
// A thin foil performing a first scattering
// of the original beam
firstScatteringFoilXSize = 0.015 *mm;
firstScatteringFoilYSize = 52.5 *mm;
firstScatteringFoilZSize = 52.5 *mm;
@@ -406,7 +406,7 @@ void PassiveCarbonBeamLine::VacuumToAirInterface()
false, 0);
logicFirstScatteringFoil -> SetVisAttributes(skyBlue);
// -------------------//
// THE KAPTON WINDOWS //
//--------------------//
@@ -432,11 +432,18 @@ void PassiveCarbonBeamLine::VacuumToAirInterface()
physiVacuumZone, false, 0);
logicKaptonWindow -> SetVisAttributes(darkOrange3);
}
/////////////////////////////////////////////////////////////////////////////
void PassiveCarbonBeamLine::HadrontherapyRippleFilter()
{
G4double defaultRippleFilterXPosition = -1638.0*mm;
G4double ripple_position=(defaultRippleFilterXPosition);
G4double RF_x = 200.0 * mm;
@@ -541,14 +548,14 @@ void PassiveCarbonBeamLine::HadrontherapyRippleFilter()
copyNumber++;
}
}
}
/////////////////////////////////////////////////////////////////////////////
void PassiveCarbonBeamLine::HadrontherapyPMMACollimator()
{
// ----------------------//
// PMMA COLLIMATOR //
// ----------------------//
@@ -619,13 +626,14 @@ void PassiveCarbonBeamLine::HadrontherapyPMMACollimator()
logicPMMACollimator -> SetVisAttributes(yellow);
}
/////////////////////////////////////////////////////////////////////////////
void PassiveCarbonBeamLine::HadrontherapyBeamMonitoring()
{
// ----------------------------
// MONITOR CHAMBER
// ----------------------------
@@ -711,7 +719,7 @@ void PassiveCarbonBeamLine::HadrontherapyBeamMonitoring()
physiFirstMonitorLayer1, false, 0);
logicFirstMonitorLayer3 -> SetVisAttributes(white);
}
/////////////////////////////////////////////////////////////////////////////
@@ -558,7 +558,7 @@ void PassiveProtonBeamLine::ConstructPassiveProtonBeamLine()
// The treatment room is invisible in the Visualisation
logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::GetInvisible());
//logicTreatmentRoom -> SetVisAttributes(G4VisAttributes::Invisible);
// Components of the Passive Proton Beam Line
HadrontherapyBeamLineSupport();