Import Geant4 10.5.0 source tree
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -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():
|
||||
+2
-2
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user