Import Geant4 10.4.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2017-06-30 10:49:55 +02:00
parent 3a5407696b
commit 1a1316fea4
2180 changed files with 237880 additions and 59109 deletions
@@ -85,8 +85,6 @@ void HadrontherapyActionInitialization::Build() const
HadrontherapySteppingAction* steppingAction = new HadrontherapySteppingAction(pRunAction);
SetUserAction(steppingAction);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -27,7 +27,6 @@
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
#include "HadrontherapyAnalysisFileMessenger.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIdirectory.hh"
@@ -52,26 +51,12 @@ HadrontherapyAnalysisFileMessenger::HadrontherapyAnalysisFileMessenger(Hadronthe
DoseMatrixCmd->SetDefaultValue("Dose.out");
DoseMatrixCmd->SetParameterName("choice",true);
// With this messenger you can:
// give a name to the generated .root file
// One can use this messenger to define a different .root file name other then the default one
#ifdef G4ANALYSIS_USE_ROOT
FileNameCmd = new G4UIcmdWithAString("/analysis/setAnalysisFile",this);
FileNameCmd->SetGuidance("Set the .root filename for the root-output");
FileNameCmd->SetDefaultValue("default.root");
FileNameCmd->SetParameterName("choice",true); ///<doc did not say what second boolean really does
FileNameCmd->AvailableForStates(G4State_Idle,G4State_PreInit);
#endif
LetCmd = new G4UIcmdWithABool("/analysis/computeLet",this);
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);
}
/////////////////////////////////////////////////////////////////////////////
@@ -80,10 +65,6 @@ HadrontherapyAnalysisFileMessenger::~HadrontherapyAnalysisFileMessenger()
delete secondaryCmd;
delete DoseMatrixCmd;
delete LetCmd;
#ifdef G4ANALYSIS_USE_ROOT
delete FileNameCmd;
#endif
}
/////////////////////////////////////////////////////////////////////////////
@@ -101,12 +82,8 @@ void HadrontherapyAnalysisFileMessenger::SetNewValue(G4UIcommand* command, G4Str
{
if ( HadrontherapyMatrix * pMatrix = HadrontherapyMatrix::GetInstance() )
{
pMatrix -> TotalEnergyDeposit();
//pMatrix -> TotalEnergyDeposit();
pMatrix -> StoreDoseFluenceAscii(newValue);
#ifdef G4ANALYSIS_USE_ROOT
pMatrix -> StoreDoseFluenceRoot();
HadrontherapyAnalysisManager::GetInstance() -> flush(); // Finalize & write the root file
#endif
}
}
@@ -115,13 +92,5 @@ void HadrontherapyAnalysisFileMessenger::SetNewValue(G4UIcommand* command, G4Str
if (HadrontherapyLet::GetInstance())
HadrontherapyLet::GetInstance() -> doCalculation = LetCmd -> GetNewBoolValue(newValue);
}
#ifdef G4ANALYSIS_USE_ROOT
else if (command == FileNameCmd)
{
AnalysisManager->SetAnalysisFileName(newValue);
HadrontherapyAnalysisManager::GetInstance() -> book(); // Book for a new ROOT TFile
}
#endif
}
@@ -52,11 +52,15 @@
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyLet.hh"
#include "PassiveProtonBeamLine.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "TrentoPassiveProtonBeamLine.hh"
#include "HadrontherapyMatrix.hh"
#include "G4SystemOfUnits.hh"
#include <cmath>
HadrontherapyDetectorConstruction* HadrontherapyDetectorConstruction::instance = 0;
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorConstruction::HadrontherapyDetectorConstruction(G4VPhysicalVolume* physicalTreatmentRoom)
@@ -87,15 +91,18 @@ aRegion(0)
// Define here the material of the water phantom and of the detector
SetPhantomMaterial("G4_WATER");
// Construct geometry (messenger commands)
SetDetectorSize(4.*cm, 4.*cm, 4.*cm);
// SetDetectorSize(4.*cm, 4.*cm, 4.*cm);
SetDetectorSize(4. *cm, 4. *cm, 4. *cm);
SetPhantomSize(40. *cm, 40. *cm, 40. *cm);
SetPhantomPosition(G4ThreeVector(20. *cm, 0. *cm, 0. *cm));
SetDetectorToPhantomPosition(G4ThreeVector(0. *cm, 18. *cm, 18. *cm));
SetDetectorToPhantomPosition(G4ThreeVector(0. *cm, 0. *cm, 0. *cm));
SetDetectorPosition();
//GetDetectorToWorldPosition();
// Write virtual parameters to the real ones and check for consistency
UpdateGeometry();
}
/////////////////////////////////////////////////////////////////////////////
@@ -109,7 +116,7 @@ HadrontherapyDetectorConstruction::~HadrontherapyDetectorConstruction()
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorConstruction* HadrontherapyDetectorConstruction::GetInstance()
{
return instance;
return instance;
}
/////////////////////////////////////////////////////////////////////////////
@@ -168,12 +175,16 @@ void HadrontherapyDetectorConstruction::ConstructPhantom()
// and inside it different quantities (dose distribution, fluence distribution, LET, etc)
// can be stored.
void HadrontherapyDetectorConstruction::ConstructDetector()
{
// Definition of the solid volume of the Detector
detector = new G4Box("Detector",
detectorSizeX/2,
detectorSizeY/2,
detectorSizeZ/2);
phantomSizeX/2,
phantomSizeY/2,
phantomSizeZ/2);
// Definition of the logic volume of the Phantom
detectorLogicalVolume = new G4LogicalVolume(detector,
@@ -205,7 +216,7 @@ void HadrontherapyDetectorConstruction::ConstructDetector()
{
aRegion = new G4Region("DetectorLog");
detectorLogicalVolume -> SetRegion(aRegion);
aRegion -> AddRootLogicalVolume(detectorLogicalVolume);
aRegion->AddRootLogicalVolume( detectorLogicalVolume );
}
}
@@ -272,7 +283,7 @@ G4bool HadrontherapyDetectorConstruction::SetPhantomMaterial(G4String material)
else
{
G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials"
" table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
" table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
return false;
}
@@ -391,11 +402,6 @@ void HadrontherapyDetectorConstruction::UpdateGeometry()
// Initialize analysis
#ifdef G4ANALYSIS_USE_ROOT
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
analysis -> flush(); // Finalize the root file
analysis -> book();
#endif
// Inform the kernel about the new geometry
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
@@ -427,27 +433,27 @@ void HadrontherapyDetectorConstruction::PrintParameters()
{
G4cout << "The (X,Y,Z) dimensions of the phantom are : (" <<
G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ',' <<
G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ',' <<
G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl;
G4BestUnit( phantom -> GetXHalfLength()*2., "Length") << ',' <<
G4BestUnit( phantom -> GetYHalfLength()*2., "Length") << ',' <<
G4BestUnit( phantom -> GetZHalfLength()*2., "Length") << ')' << G4endl;
G4cout << "The (X,Y,Z) dimensions of the detector are : (" <<
G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ',' <<
G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ',' <<
G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl;
G4BestUnit( detector -> GetXHalfLength()*2., "Length") << ',' <<
G4BestUnit( detector -> GetYHalfLength()*2., "Length") << ',' <<
G4BestUnit( detector -> GetZHalfLength()*2., "Length") << ')' << G4endl;
G4cout << "Displacement between Phantom and World is: ";
G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") <<
"DY= "<< G4BestUnit(phantomPosition.getY(),"Length") <<
"DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl;
"DY= "<< G4BestUnit(phantomPosition.getY(),"Length") <<
"DZ= "<< G4BestUnit(phantomPosition.getZ(),"Length") << G4endl;
G4cout << "The (X,Y,Z) sizes of the Voxels are: (" <<
G4BestUnit(sizeOfVoxelAlongX, "Length") << ',' <<
G4BestUnit(sizeOfVoxelAlongY, "Length") << ',' <<
G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl;
G4BestUnit(sizeOfVoxelAlongX, "Length") << ',' <<
G4BestUnit(sizeOfVoxelAlongY, "Length") << ',' <<
G4BestUnit(sizeOfVoxelAlongZ, "Length") << ')' << G4endl;
G4cout << "The number of Voxels along (X,Y,Z) is: (" <<
numberOfVoxelsAlongX << ',' <<
numberOfVoxelsAlongX << ',' <<
numberOfVoxelsAlongY <<',' <<
numberOfVoxelsAlongZ << ')' << G4endl;
}
@@ -33,7 +33,7 @@
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAString.hh"
#include "G4SystemOfUnits.hh"
#include "G4UIcmdWithABool.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorMessenger::HadrontherapyDetectorMessenger(HadrontherapyDetectorConstruction* detector)
@@ -110,6 +110,10 @@ HadrontherapyDetectorMessenger::HadrontherapyDetectorMessenger(HadrontherapyDete
changeTheDetectorVoxelCmd -> SetUnitCandidates("nm um mm cm");
changeTheDetectorVoxelCmd -> AvailableForStates(G4State_Idle);
}
/////////////////////////////////////////////////////////////////////////////
@@ -124,6 +128,7 @@ HadrontherapyDetectorMessenger::~HadrontherapyDetectorMessenger()
delete changeTheDetectorSizeCmd;
delete changeTheDetectorToPhantomPositionCmd;
delete changeTheDetectorVoxelCmd;
}
/////////////////////////////////////////////////////////////////////////////
@@ -163,4 +168,5 @@ void HadrontherapyDetectorMessenger::SetNewValue(G4UIcommand* command,G4String n
{
hadrontherapyDetector -> UpdateGeometry();
}
}
@@ -324,7 +324,7 @@ void HadrontherapyDetectorROGeometry::ConstructSD()
G4String sensitiveDetectorName = "RODetector";
HadrontherapyDetectorSD* detectorSD = new HadrontherapyDetectorSD(sensitiveDetectorName);
G4SDManager::GetSDMpointer()->AddNewDetector(detectorSD);
SetSensitiveDetector(sensitiveLogicalVolume,detectorSD);
@@ -35,202 +35,169 @@
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyLet.hh"
#include "G4Track.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "G4SystemOfUnits.hh"
#include "HadrontherapyMatrix.hh"
#include "G4SteppingManager.hh"
#include "G4TrackVector.hh"
#include "HadrontherapySteppingAction.hh"
#include "G4ios.hh"
#include "G4SteppingManager.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4StepPoint.hh"
#include "G4TrackStatus.hh"
#include "G4TrackVector.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4UserEventAction.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "HadrontherapyRunAction.hh"
#include "G4SystemOfUnits.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorSD::HadrontherapyDetectorSD(G4String name):
G4VSensitiveDetector(name)
{
G4VSensitiveDetector(name)
{
G4String HCname;
collectionName.insert(HCname="HadrontherapyDetectorHitsCollection");
HitsCollection = NULL;
HitsCollection = NULL;
sensitiveDetectorName = name;
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyDetectorSD::~HadrontherapyDetectorSD()
{
{
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorSD::Initialize(G4HCofThisEvent*)
{
HitsCollection = new HadrontherapyDetectorHitsCollection(sensitiveDetectorName,
collectionName[0]);
collectionName[0]);
}
/////////////////////////////////////////////////////////////////////////////
G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
{
if (aStep -> GetPreStepPoint() -> GetPhysicalVolume() -> GetName() != "RODetectorZDivisionPhys") return false;
if (aStep -> GetPreStepPoint() -> GetPhysicalVolume() -> GetName() != "RODetectorZDivisionPhys") return false;
// Get kinetic energy
G4Track * theTrack = aStep -> GetTrack();
G4double kineticEnergy = theTrack -> GetKineticEnergy();
G4double kineticEnergy = theTrack -> GetKineticEnergy();
G4ParticleDefinition *particleDef = theTrack -> GetDefinition();
//Get particle name
G4String particleName = particleDef -> GetParticleName();
//Get particle name
G4String particleName = particleDef -> GetParticleName();
G4int pdg = particleDef ->GetPDGEncoding();
// Get unique track_id (in an event)
G4int trackID = theTrack -> GetTrackID();
G4double energyDeposit = aStep -> GetTotalEnergyDeposit();
G4double DX = aStep -> GetStepLength();
G4int Z = particleDef-> GetAtomicNumber();
G4int A = particleDef-> GetAtomicMass();
// Read voxel indexes: i is the x index, k is the z index
const G4VTouchable* touchable = aStep->GetPreStepPoint()->GetTouchable();
G4int k = touchable->GetReplicaNumber(0);
G4int i = touchable->GetReplicaNumber(2);
G4int j = touchable->GetReplicaNumber(1);
G4StepPoint* PreStep = aStep->GetPreStepPoint();
// Read voxel indexes: i is the x index, k is the z index
const G4VTouchable* touchable = aStep->GetPreStepPoint()->GetTouchable();
G4int k = touchable->GetReplicaNumber(0);
G4int i = touchable->GetReplicaNumber(2);
G4int j = touchable->GetReplicaNumber(1);
G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
G4String namePre = volumePre->GetName();
//G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
#ifdef G4ANALYSIS_USE_ROOT
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
#endif
HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance();
HadrontherapyLet* let = HadrontherapyLet::GetInstance();
// ******************** let ***************************
if (let)
{
if ( !(Z==0 && A==1) ) // All but not neutrons
{
if( energyDeposit>0. && DX >0. )
{
if (pdg !=22) // not gamma
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i, j, k);
}
else if (kineticEnergy > 50.*keV) // gamma cut
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i , j, k);
}
}
}
}
G4int* hitTrack = matrix -> GetHitTrack(i,j,k);
// ******************** let ***************************
if (let)
{
if ( !(Z==0 && A==1) ) // All but not neutrons
{
if( energyDeposit>0. && DX >0. )
{
if (pdg !=22) // not gamma
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i, j, k);
}
else if (kineticEnergy > 50.*keV) // gamma cut
{
let -> FillEnergySpectrum(trackID, particleDef,energyDeposit, DX, i , j, k);
}
}
}
}
if (matrix)
{
// Increment Fluences & accumulate energy spectra
// Hit voxels are marked with track_id throught hitTrack matrix
G4int* hitTrack = matrix -> GetHitTrack(i,j,k); // hitTrack MUST BE cleared at every eventAction!
if ( *hitTrack != trackID )
{
*hitTrack = trackID;
/*
* Fill FLUENCE data for every single nuclide
* Exclude e-, neutrons, gamma, ...
*/
if ( Z >= 1) matrix -> Fill(trackID, particleDef, i, j, k, 0, true);
#ifdef G4ANALYSIS_USE_ROOT
/*
// Fragments kinetic energy (ntuple)
if (trackID !=1 && Z>=1)
{
// First step kinetic energy for every fragment
analysis -> FillKineticFragmentTuple(i, j, k, A, Z, kineticEnergy/MeV);
}
// Kinetic energy spectra for primary particles
if ( trackID == 1 && i == 0)
{
// First step kinetic energy for primaries only
analysis -> FillKineticEnergyPrimaryNTuple(i, j, k, kineticEnergy/MeV);
}
*/
#endif
}
if(energyDeposit != 0)
{
/*
* This method will fill a dose matrix for every single nuclide.
* A method of the HadrontherapyMatrix class (StoreDoseFluenceAscii())
* is called automatically at the end of main (or via the macro command /analysis/writeDoseFile.
* It permits to store all dose/fluence data into a single plane ASCII file.
*/
// if (A==1 && Z==1) // primary and sec. protons
if ( Z>=1 ) // exclude e-, neutrons, gamma, ...
matrix -> Fill(trackID, particleDef, i, j, k, energyDeposit);
/*
* Create a hit with the information of position is in the detector
*/
HadrontherapyDetectorHit* detectorHit = new HadrontherapyDetectorHit();
detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit);
HitsCollection -> insert(detectorHit);
}
// Increment Fluences & accumulate energy spectra
// Hit voxels are marked with track_id throught hitTrack matrix
//G4int* hitTrack = matrix -> GetHitTrack(i,j,k); // hitTrack MUST BE cleared at every eventAction!
if ( *hitTrack != trackID )
{
*hitTrack = trackID;
/*
* Fill FLUENCE data for every single nuclide
* Exclude e-, neutrons, gamma, ...
*/
if ( Z >= 1) matrix -> Fill(trackID, particleDef, i, j, k, 0, true);
}
if(energyDeposit != 0)
{
/*
* This method will fill a dose matrix for every single nuclide.
* A method of the HadrontherapyMatrix class (StoreDoseFluenceAscii())
* is called automatically at the end of main (or via the macro command /analysis/writeDoseFile.
* It permits to store all dose/fluence data into a single plane ASCII file.
*/
// if (A==1 && Z==1) // primary and sec. protons
if ( Z>=1 ) // exclude e-, neutrons, gamma, ...
matrix -> Fill(trackID, particleDef, i, j, k, energyDeposit);
/*
* Create a hit with the information of position is in the detector
*/
HadrontherapyDetectorHit* detectorHit = new HadrontherapyDetectorHit();
detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit);
HitsCollection -> insert(detectorHit);
}
}
#ifdef G4ANALYSIS_USE_ROOT
if(energyDeposit != 0)
{
if(trackID != 1)
{
if (particleName == "proton")
analysis -> SecondaryProtonEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "neutron")
analysis -> SecondaryNeutronEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "alpha")
analysis -> SecondaryAlphaEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "gamma")
analysis -> SecondaryGammaEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "e-")
analysis -> SecondaryElectronEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "triton")
analysis -> SecondaryTritonEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "deuteron")
analysis -> SecondaryDeuteronEnergyDeposit(i, energyDeposit/MeV);
else if (particleName == "pi+" || particleName == "pi-" || particleName == "pi0")
analysis -> SecondaryPionEnergyDeposit(i, energyDeposit/MeV);
}
}
#endif
return true;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyDetectorSD::EndOfEvent(G4HCofThisEvent* HCE)
{
static G4int HCID = -1;
if(HCID < 0)
{
HCID = GetCollectionID(0);
HCID = GetCollectionID(0);
}
HCE -> AddHitsCollection(HCID,HitsCollection);
}
@@ -43,64 +43,58 @@
/////////////////////////////////////////////////////////////////////////////
HadrontherapyEventAction::HadrontherapyEventAction() :
drawFlag("all" ),printModulo(10), pointerEventMessenger(0)
{
hitsCollectionID = -1;
pointerEventMessenger = new HadrontherapyEventActionMessenger(this);
drawFlag("all" ),printModulo(10), pointerEventMessenger(0)
{
hitsCollectionID = -1;
pointerEventMessenger = new HadrontherapyEventActionMessenger(this);
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyEventAction::~HadrontherapyEventAction()
{
delete pointerEventMessenger;
}
delete pointerEventMessenger;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyEventAction::BeginOfEventAction(const G4Event* evt)
{
G4int evtNb = evt->GetEventID();
//printing survey
if (evtNb%printModulo == 0)
G4cout << "\n---> Begin of Event: " << evtNb << G4endl;
G4SDManager* pSDManager = G4SDManager::GetSDMpointer();
if(hitsCollectionID == -1)
hitsCollectionID = pSDManager -> GetCollectionID("HadrontherapyDetectorHitsCollection");
void HadrontherapyEventAction::BeginOfEventAction(const G4Event*)
{
G4SDManager* pSDManager = G4SDManager::GetSDMpointer();
if(hitsCollectionID == -1)
hitsCollectionID = pSDManager -> GetCollectionID("HadrontherapyDetectorHitsCollection");
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyEventAction::EndOfEventAction(const G4Event* evt)
{
if(hitsCollectionID < 0)
return;
G4HCofThisEvent* HCE = evt -> GetHCofThisEvent();
// Clear voxels hit list
HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance();
if (matrix) matrix -> ClearHitTrack();
if(HCE)
{
HadrontherapyDetectorHitsCollection* CHC = (HadrontherapyDetectorHitsCollection*)(HCE -> GetHC(hitsCollectionID));
if(CHC)
{
if(matrix)
{
// Fill the matrix with the information: voxel and associated energy deposit
// in the detector at the end of the event
G4int HitCount = CHC -> entries();
for (G4int h=0; h<HitCount; h++)
{
G4int i = ((*CHC)[h]) -> GetXID();
G4int j = ((*CHC)[h]) -> GetYID();
G4int k = ((*CHC)[h]) -> GetZID();
G4double energyDeposit = ((*CHC)[h]) -> GetEdep();
matrix -> Fill(i, j, k, energyDeposit/MeV);
}
}
{
if(hitsCollectionID < 0)
return;
G4HCofThisEvent* HCE = evt -> GetHCofThisEvent();
// Clear voxels hit list
HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance();
if (matrix) matrix -> ClearHitTrack();
if(HCE)
{
HadrontherapyDetectorHitsCollection* CHC = (HadrontherapyDetectorHitsCollection*)(HCE -> GetHC(hitsCollectionID));
if(CHC)
{
if(matrix)
{
// Fill the matrix with the information: voxel and associated energy deposit
// in the detector at the end of the event
G4int HitCount = CHC -> entries();
for (G4int h=0; h<HitCount; h++)
{
G4int i = ((*CHC)[h]) -> GetXID();
G4int j = ((*CHC)[h]) -> GetYID();
G4int k = ((*CHC)[h]) -> GetZID();
G4double energyDeposit = ((*CHC)[h]) -> GetEdep();
matrix -> Fill(i, j, k, energyDeposit/MeV);
}
}
}
}
}
}
@@ -33,6 +33,9 @@
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
#include "G4UnitsTable.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyEventActionMessenger::HadrontherapyEventActionMessenger(HadrontherapyEventAction* EvAct)
@@ -37,6 +37,7 @@
#include "G4RunManager.hh"
#include "G4VUserParallelWorld.hh"
#include "G4ThreeVector.hh"
#include "TrentoPassiveProtonBeamLine.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyGeometryController::HadrontherapyGeometryController()
@@ -62,6 +63,11 @@ void HadrontherapyGeometryController::SetGeometry(G4String name)
{
registerGeometry(new LaserDrivenBeamLine());
}
else if(name == "TrentoLine")
{
registerGeometry(new TrentoPassiveProtonBeamLine());
}
else
{
G4cout <<"Unknown geometry: " << name << ". Geometry not changed." << G4endl;
@@ -57,17 +57,12 @@ HadrontherapyGeometryMessenger::~HadrontherapyGeometryMessenger()
{
delete changeTheGeometryDir;
delete changeTheGeometryCmd;
// delete changeTheDetectorCmd;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyGeometryMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
/* if( command == changeTheDetectorCmd )
{
hadrontherapyGeometryController -> SetDetector (newValue);
}
else*/
if( command == changeTheGeometryCmd )
{
hadrontherapyGeometryController -> SetGeometry (newValue);
@@ -56,10 +56,7 @@ HadrontherapyInteractionParameters::HadrontherapyInteractionParameters(G4bool wa
data(G4cout.rdbuf()),
pMessenger(0),
beamFlag(false)
#ifdef G4ANALYSIS_USE_ROOT
,theRootCanvas(0),
theRootGraph(0)
#endif
{
if (wantMessenger) pMessenger = new HadrontherapyParameterMessenger(this);
}
@@ -117,10 +114,7 @@ bool HadrontherapyInteractionParameters::GetStoppingTable(const G4String& vararg
data << std::setw(16) << energy[i] << massDedx[i] << G4endl;
}
outfile.close();
// This will plot
#ifdef G4ANALYSIS_USE_ROOT
PlotStopping("pdf");
#endif
// This will plot
// Info to user
G4String ofName = (filename == "") ? "User terminal": filename;
@@ -132,53 +126,6 @@ bool HadrontherapyInteractionParameters::GetStoppingTable(const G4String& vararg
ofName << "\"" << G4endl;
return true;
}
///////////////////////////////////////////////////////////////////////////////////
// Save Plot
#ifdef G4ANALYSIS_USE_ROOT
void HadrontherapyInteractionParameters::PlotStopping(const G4String& filetype)
{
if (!theRootCanvas)
{
gROOT->Reset();
gROOT->SetStyle("Plain");
theRootCanvas = new TCanvas("theRootCanvas","Interaction Parameters",200, 10, 600,400);
theRootCanvas -> SetFillColor(20);
theRootCanvas -> SetBorderMode(1);
theRootCanvas -> SetBorderSize(1);
theRootCanvas -> SetFrameBorderMode(0);
theRootCanvas -> SetGrid();
// Use global pad: root manual pgg 109,...
}
if (theRootGraph) delete theRootGraph;
theRootGraph = new TGraph(energy.size(), &energy[0], &massDedx[0]);
//theRootGraph = new TGraph();
axisX = theRootGraph -> GetXaxis(),
axisY = theRootGraph -> GetYaxis();
axisX -> SetTitle("MeV");
axisY -> SetTitle("Stopping Power (MeV cm2/g)");
//axisX -> SetNdivisions(500,kTRUE);
//axisX -> SetTickLength(0.03);
//axisX -> SetLabelOffset(2.005);
axisX -> SetAxisColor(2);
axisY -> SetAxisColor(2);
gPad -> SetLogx(1);
gPad -> SetLogy(1);
theRootGraph -> SetMarkerColor(4);
theRootGraph -> SetMarkerStyle(20);// circle
theRootGraph -> SetMarkerSize(.5);
G4String gName = particle.substr(0, particle.find("[") ); // cut excitation energy
gName = gName + "_" + material;
G4String fName = "./referenceData/interaction/" + gName + "." + filetype;
theRootGraph -> SetTitle(gName);
theRootGraph -> Draw("AP");
//theRootCanvas -> Update();
//theRootCanvas -> Draw();
theRootCanvas -> SaveAs(fName);
}
#endif
// Search for user material choice inside G4NistManager database
G4Material* HadrontherapyInteractionParameters::GetNistMaterial(G4String mat)
{
@@ -28,7 +28,8 @@
#include "HadrontherapyDetectorConstruction.hh"
#include "HadrontherapyLet.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyInteractionParameters.hh"
#include "HadrontherapyPrimaryGeneratorAction.hh"
#include "HadrontherapyMatrix.hh"
@@ -208,56 +209,77 @@ void HadrontherapyLet::StoreLetAscii()
ofs << G4endl;
// Write data
G4AnalysisManager* LetFragmentTuple = G4AnalysisManager::Instance();
LetFragmentTuple->SetVerboseLevel(1);
LetFragmentTuple->SetFirstHistoId(1);
LetFragmentTuple->SetFirstNtupleId(1);
LetFragmentTuple ->OpenFile("Let");
LetFragmentTuple ->CreateNtuple("coordinate", "Let");
LetFragmentTuple ->CreateNtupleIColumn("i");//1
LetFragmentTuple ->CreateNtupleIColumn("j");//2
LetFragmentTuple ->CreateNtupleIColumn("k");//3
LetFragmentTuple ->CreateNtupleDColumn("TotalLetD");//4
LetFragmentTuple ->CreateNtupleIColumn("A");//5
LetFragmentTuple ->CreateNtupleIColumn("Z");//6
LetFragmentTuple ->CreateNtupleDColumn("IonLETD");//7
LetFragmentTuple ->FinishNtuple();
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
G4int v = matrix -> Index(i, j, k);
// row write
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
if(ionLetStore[l].letDN)
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();
G4cout << "Let is being written to " << filename << G4endl;
}
LetFragmentTuple->Write();
LetFragmentTuple->CloseFile();
}
}
}
void HadrontherapyLet::StoreLetRoot()
{
#ifdef G4ANALYSIS_USE_ROOT
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
G4int v = matrix -> Index(i, j, k);
for (size_t ion=0; ion < ionLetStore.size(); ion++)
{
analysis -> FillLetFragmentTuple( i, j, k, ionLetStore[ion].A, ionLetStore[ion].Z, ionLetStore[ion].letDN[v]);
}
}
#endif
}
}
@@ -32,57 +32,91 @@
#include <iomanip>
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "HadrontherapyPrimaryGeneratorAction.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
#include "G4ParticleGun.hh"
#include "HadrontherapySteppingAction.hh"
#include "HadrontherapyAnalysisFileMessenger.hh"
#include "G4SystemOfUnits.hh"
#include <time.h>
HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::instance = 0;
HadrontherapyAnalysisManager::HadrontherapyAnalysisManager()
{
fMess = new HadrontherapyAnalysisFileMessenger(this);
}
HadrontherapyAnalysisManager::~HadrontherapyAnalysisManager()
{
delete fMess;
}
HadrontherapyAnalysisManager* HadrontherapyAnalysisManager::GetInstance(){
if (instance == 0) instance = new HadrontherapyAnalysisManager;
return instance;
}
// Units definition: CLHEP/Units/SystemOfUnits.h
//
HadrontherapyMatrix* HadrontherapyMatrix::instance = NULL;
G4bool HadrontherapyMatrix::secondary = false;
// Only return a pointer to matrix
HadrontherapyMatrix* HadrontherapyMatrix::GetInstance()
HadrontherapyMatrix* HadrontherapyMatrix::GetInstance()
{
return instance;
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)
// 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)
{
if (instance) delete instance;
instance = new HadrontherapyMatrix(voxelX, voxelY, voxelZ, mass);
instance -> Initialize();
return instance;
if (instance) delete instance;
instance = new HadrontherapyMatrix(voxelX, voxelY, voxelZ, mass);
instance -> Initialize();
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)
// orthogonal to the beam axis
numberOfVoxelAlongX = voxelX;
numberOfVoxelAlongY = voxelY;
numberOfVoxelAlongZ = voxelZ;
massOfVoxel = mass;
// Create the dose matrix
matrix = new G4double[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
if (matrix)
{
G4cout << "HadrontherapyMatrix: Memory space to store physical dose into " <<
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated " << G4endl;
}
else G4Exception("HadrontherapyMatrix::HadrontherapyMatrix()", "Hadrontherapy0005", FatalException, "Can't allocate memory to store physical dose!");
// Hit voxel (TrackID) marker
// This array mark the status of voxel, if a hit occur, with the trackID of the particle
// Must be initialized
hitTrack = new G4int[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
ClearHitTrack();
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)
// orthogonal to the beam axis
numberOfVoxelAlongX = voxelX;
numberOfVoxelAlongY = voxelY;
numberOfVoxelAlongZ = voxelZ;
massOfVoxel = mass;
// Create the dose matrix
matrix = new G4double[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
if (matrix)
{
G4cout << "HadrontherapyMatrix: Memory space to store physical dose into " <<
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated " << G4endl;
}
else G4Exception("HadrontherapyMatrix::HadrontherapyMatrix()", "Hadrontherapy0005", FatalException, "Can't allocate memory to store physical dose!");
// Hit voxel (TrackID) marker
// This array mark the status of voxel, if a hit occur, with the trackID of the particle
// Must be initialized
hitTrack = new G4int[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
ClearHitTrack();
}
/////////////////////////////////////////////////////////////////////////////
@@ -90,7 +124,6 @@ HadrontherapyMatrix::~HadrontherapyMatrix()
{
delete[] matrix;
delete[] hitTrack;
// free fluences/dose data memory
Clear();
}
@@ -99,314 +132,332 @@ void HadrontherapyMatrix::Clear()
{
for (size_t i=0; i<ionStore.size(); i++)
{
delete[] ionStore[i].dose;
delete[] ionStore[i].fluence;
delete[] ionStore[i].dose;
delete[] ionStore[i].fluence;
}
ionStore.clear();
}
/////////////////////////////////////////////////////////////////////////////
// Initialise the elements of the matrix to zero
void HadrontherapyMatrix::Initialize()
{
{
// Clear ions store
Clear();
// Clear dose
for(int i=0;i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ;i++)
{
matrix[i] = 0;
matrix[i] = 0;
}
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Print generated nuclides list
/////////////////////////////////////////////////////////////////////////////
// Print generated nuclides list
void HadrontherapyMatrix::PrintNuclides()
{
for (size_t i=0; i<ionStore.size(); i++)
{
G4cout << ionStore[i].name << G4endl;
G4cout << ionStore[i].name << G4endl;
}
}
/////////////////////////////////////////////////////////////////////////////
// Clear Hit voxel (TrackID) markers
/////////////////////////////////////////////////////////////////////////////
// Clear Hit voxel (TrackID) markers
void HadrontherapyMatrix::ClearHitTrack()
{
for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0;
for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0;
}
// Return Hit status
// Return Hit status
G4int* HadrontherapyMatrix::GetHitTrack(G4int i, G4int j, G4int k)
{
return &(hitTrack[Index(i,j,k)]);
return &(hitTrack[Index(i,j,k)]);
}
/////////////////////////////////////////////////////////////////////////////
// Dose methods...
// Fill DOSE/fluence matrix for secondary particles:
// 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)
// Fill DOSE/fluence matrix for secondary particles:
// 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,
G4double energyDeposit,
G4bool fluence)
G4ParticleDefinition* particleDef,
G4int i, G4int j, G4int k,
G4double energyDeposit,
G4bool fluence)
{
if ( (energyDeposit <=0. && !fluence) || !secondary) return false;
// Get Particle Data Group particle ID
// Get Particle Data Group particle ID
G4int PDGencoding = particleDef -> GetPDGEncoding();
PDGencoding -= PDGencoding%10;
// Search for already allocated data...
for (size_t l=0; l < ionStore.size(); l++)
{
if (ionStore[l].PDGencoding == PDGencoding )
{ // Is it a primary or a secondary particle?
if ( (trackID ==1 && ionStore[l].isPrimary) || (trackID !=1 && !ionStore[l].isPrimary))
{
if (energyDeposit > 0.) ionStore[l].dose[Index(i, j, k)] += energyDeposit;
// Fill a matrix per each ion with the fluence
if (fluence) ionStore[l].fluence[Index(i, j, k)]++;
return true;
}
}
if (ionStore[l].PDGencoding == PDGencoding )
{ // Is it a primary or a secondary particle?
if ( (trackID ==1 && ionStore[l].isPrimary) || (trackID !=1 && !ionStore[l].isPrimary))
{
if (energyDeposit > 0.)
ionStore[l].dose[Index(i, j, k)] += energyDeposit;
// Fill a matrix per each ion with the fluence
if (fluence) ionStore[l].fluence[Index(i, j, k)]++;
return true;
}
}
}
G4int Z = particleDef-> GetAtomicNumber();
G4int A = particleDef-> GetAtomicMass();
G4String fullName = particleDef -> GetParticleName();
G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy
// Let's put a new particle in our store...
ion newIon =
G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy
// Let's put a new particle in our store...
ion newIon =
{
(trackID == 1) ? true:false,
PDGencoding,
name,
name.length(),
Z,
A,
new G4double[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ],
new unsigned int[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ]
};
// Initialize data
(trackID == 1) ? true:false,
PDGencoding,
name,
name.length(),
Z,
A,
new G4double[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ],
new unsigned int[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ]
};
// Initialize data
if (newIon.dose && newIon.fluence)
{
for(G4int q=0; q<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; q++)
{
newIon.dose[q] = 0.;
newIon.fluence[q] = 0;
}
if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit;
if (fluence) newIon.fluence[Index(i, j, k)]++;
ionStore.push_back(newIon);
// TODO Put some verbosity check
/*
G4cout << "Memory space to store the DOSE/FLUENCE into " <<
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated for the nuclide " << newIon.name <<
" (Z = " << Z << ", A = " << A << ")" << G4endl ;
*/
return true;
for(G4int q=0; q<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; q++)
{
newIon.dose[q] = 0.;
newIon.fluence[q] = 0;
}
if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit;
if (fluence) newIon.fluence[Index(i, j, k)]++;
ionStore.push_back(newIon);
return true;
}
else // XXX Out of memory! XXX
{
return false;
return false;
}
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Methods to store data to filenames...
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
// General method to store matrix data to filename
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Methods to store data to filenames...
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
// General method to store matrix data to filename
void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize)
{
if (data)
{
ofs.open(file, std::ios::out);
if (ofs.is_open())
{
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);
// Check for data type: u_int, G4double, XXX
if (psize == sizeof(unsigned int))
{
unsigned int* pdata = (unsigned int*)data;
if (pdata[n]) ofs << i << '\t' << j << '\t' <<
k << '\t' << pdata[n] << G4endl;
}
else if (psize == sizeof(G4double))
{
G4double* pdata = (G4double*)data;
if (pdata[n]) ofs << i << '\t' << j << '\t' <<
k << '\t' << pdata[n] << G4endl;
}
}
ofs.close();
}
ofs.open(file, std::ios::out);
if (ofs.is_open())
{
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);
if (psize == sizeof(unsigned int))
{
unsigned int* pdata = (unsigned int*)data;
if (pdata[n])
ofs << i << '\t' << j << '\t' << k << '\t' << pdata[n] << G4endl;
}
else if (psize == sizeof(G4double))
{
G4double* pdata = (G4double*)data;
if (pdata[n]) ofs << i << '\t' << j << '\t' << k << '\t' << pdata[n] << G4endl;
}
}
ofs.close();
}
}
}
// Store fluence per single ion in multiple files
// Store fluence per single ion in multiple files
void HadrontherapyMatrix::StoreFluenceData()
{
for (size_t i=0; i < ionStore.size(); i++){
StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int));
StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int));
}
}
// Store dose per single ion in multiple files
// Store dose per single ion in multiple files
void HadrontherapyMatrix::StoreDoseData()
{
for (size_t i=0; i < ionStore.size(); i++){
StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double));
StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double));
}
}
/////////////////////////////////////////////////////////////////////////
// Store dose for all ions into a single file and into ntuples.
// Please note that this function is called via messenger commands
// defined in the HadrontherapyAnalysisFileMessenger.cc class file
/////////////////////////////////////////////////////////////////////////
// Store dose for all ions into a single file and into ntuples.
// 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;
// Sort like periodic table
std::sort(ionStore.begin(), ionStore.end());
G4cout << "Dose is being written to " << filename << G4endl;
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 <<
"i\tj\tk\t";
// Total dose
ofs << std::setw(width) << "Dose(Gy)";
if (secondary)
{
for (size_t l=0; l < ionStore.size(); l++)
{
G4String a = (ionStore[l].isPrimary) ? "_1":""; // is it a primary?
ofs << std::setw(width) << ionStore[l].name + a <<
std::setw(width) << ionStore[l].name + a;
}
ofs << G4endl;
/*
* PDGencondig
*/
/*
ofs << std::setprecision(6) << std::left <<
"0\t0\t0\t";
// Total dose
ofs << std::setw(width) << '0';
for (size_t l=0; l < ionStore.size(); l++)
{
ofs << std::setw(width) << ionStore[l].PDGencoding <<
std::setw(width) << ionStore[l].PDGencoding;
}
ofs << G4endl;
*/
}
// 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
if (matrix[n])
{
ofs << G4endl;
ofs << i << '\t' << j << '\t' << k << '\t';
// Total dose
ofs << std::setw(width) << (matrix[n]/massOfVoxel)/doseUnit;
if (secondary)
{
for (size_t l=0; l < ionStore.size(); l++)
{
// Fill ASCII file rows
ofs << std::setw(width) << ionStore[l].dose[n]/massOfVoxel/doseUnit <<
std::setw(width) << ionStore[l].fluence[n];
}
}
}
}
ofs.close();
// Write the voxels index and the list of particles/ions
ofs << std::setprecision(6) << std::left <<
"i\tj\tk\t";
// Total dose
ofs << std::setw(width) << "Dose(Gy)";
if (secondary)
{
for (size_t l=0; l < ionStore.size(); l++)
{
G4String a = (ionStore[l].isPrimary) ? "_1":""; // is it a primary?
ofs << std::setw(width) << ionStore[l].name + a <<
std::setw(width) << ionStore[l].name + a;
}
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++)
{
// Fill ASCII file rows
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();
}
}
/////////////////////////////////////////////////////////////////////////////
#ifdef G4ANALYSIS_USE_ROOT
void HadrontherapyMatrix::StoreDoseFluenceRoot()
{
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
if (analysis -> IsTheTFile())
{
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);
for (size_t l=0; l < ionStore.size(); l++)
{
// Do the same work for .root file: fill dose/fluence ntuple
analysis -> FillVoxelFragmentTuple( i, j, k,
ionStore[l].A,
ionStore[l].Z,
ionStore[l].dose[n]/massOfVoxel/doseUnit,
ionStore[l].fluence[n] );
}
}
}
}
#endif
void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k,
G4double energyDeposit)
G4double energyDeposit)
{
if (matrix)
matrix[Index(i,j,k)] += energyDeposit;
matrix[Index(i,j,k)] += energyDeposit;
// Store the energy deposit in the matrix element corresponding
// to the phantom voxel
}
void HadrontherapyMatrix::TotalEnergyDeposit()
{
// Convert energy deposited to dose.
// Store the information of the matrix in a ntuple and in
// a 1D Histogram
#ifdef G4ANALYSIS_USE_ROOT
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
#endif
if (matrix)
{
for(G4int i = 0; i < numberOfVoxelAlongX; i++)
for(G4int j = 0; j < numberOfVoxelAlongY; j++)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
#ifdef G4ANALYSIS_USE_ROOT
G4int n = Index(i,j,k);
if (analysis -> IsTheTFile() )
{
analysis -> FillEnergyDeposit(i, j, k, matrix[n]/massOfVoxel/doseUnit);
analysis -> BraggPeak(i, matrix[n]/massOfVoxel/doseUnit);
}
#endif
}
}
}
@@ -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("ModoulWeight.txt")
FileName("Modulators/Modulator009_02.txt")
{
pi=4*atan(1.);
StepNumbers=22;
@@ -28,11 +28,11 @@
//
//
// ****** SUGGESTED PHYSICS FOR ACCURATE SIMULATIONS *********
// ****** IN MEDICAL PHYSICS APPLI CATIONS *********
//
// At moment, if accurate simulations are necessary, we suggest the use of the
// Physics Lists 'HADRONTHERAPY_1';
// 'HADRONTHERAPY_1' and 'HADRONTHERAPY_2' are both suggested;
// It can be activated inside any macro file using the command:
// /Physics/addPhysics HADRONTHERAPY_1
// /Physics/addPhysics HADRONTHERAPY_1 (HADRONTHERAPY_2)
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
@@ -43,16 +43,10 @@
#include "HadrontherapyStepMax.hh"
#include "G4PhysListFactory.hh"
#include "G4VPhysicsConstructor.hh"
// Local physic directly implemented in the Hadronthrapy directory
// Physic dedicated to the ion-ion inelastic processes
//
#include "LocalIonIonInelasticPhysic.hh"
#include "G4HadronPhysicsQGSP_BIC_HP.hh"
#include "G4HadronPhysicsQGSP_BIC.hh"
#include "G4EmStandardPhysics_option3.hh"
#include "G4EmStandardPhysics_option4.hh"
#include "G4EmStandardPhysics.hh"
#include "G4EmExtraPhysics.hh"
#include "G4StoppingPhysics.hh"
#include "G4DecayPhysics.hh"
@@ -81,41 +75,13 @@ HadrontherapyPhysicsList::HadrontherapyPhysicsList() : G4VModularPhysicsList()
cutForElectron = defaultCutValue;
cutForPositron = defaultCutValue;
pMessenger = new HadrontherapyPhysicsListMessenger(this);
pMessenger = new HadrontherapyPhysicsListMessenger(this);
SetVerboseLevel(1);
// ****** Definition of defaults for the physics processes *****
// ****** in case no physics is called by the macro file *****
//
// The default physics corresponds to the actual QGSP_BIC_HP list
// but with the following differences:
// --> G4EmStandardPhysics_option4 for the electromagnetic processes
// is used n place of the less accurate G4EmStandardPhysics
// --> The G4RadioactiveDecayPhysics is add
// --> G4HadronPhysicsQGSP_BIC is used in place of G4HadronPhysicsQGSP_BIC_HP
// --> G4HadronElasticPhysics is used in place of G4HadronElasticPhysics_HP
decay_List = new G4DecayPhysics();
// Elecromagnetic physics
//
emPhysicsList = new G4EmStandardPhysics_option4();
emName = G4String("emstandard_opt4");
// Hadronic physics
//
hadronPhys.push_back( new G4DecayPhysics());
hadronPhys.push_back( new G4RadioactiveDecayPhysics());
hadronPhys.push_back( new G4IonBinaryCascadePhysics());
hadronPhys.push_back( new G4EmExtraPhysics());
hadronPhys.push_back( new G4HadronElasticPhysics());
hadronPhys.push_back( new G4StoppingPhysics());
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC());
// Decay physics
//
decay_List = new G4DecayPhysics();
radioactiveDecay_List = new G4RadioactiveDecayPhysics();
}
/////////////////////////////////////////////////////////////////////////////
@@ -123,8 +89,8 @@ HadrontherapyPhysicsList::~HadrontherapyPhysicsList()
{
delete pMessenger;
delete emPhysicsList;
delete decay_List;
delete radioactiveDecay_List;
delete decay_List;
//delete radioactiveDecay_List;
hadronPhys.clear();
for(size_t i=0; i<hadronPhys.size(); i++)
{
@@ -136,6 +102,7 @@ HadrontherapyPhysicsList::~HadrontherapyPhysicsList()
void HadrontherapyPhysicsList::ConstructParticle()
{
decay_List -> ConstructParticle();
}
/////////////////////////////////////////////////////////////////////////////
@@ -145,10 +112,11 @@ void HadrontherapyPhysicsList::ConstructProcess()
//
AddTransportation();
// Electromagnetic physics
//
decay_List -> ConstructProcess();
emPhysicsList -> ConstructProcess();
em_config.AddModels();
//em_config.AddModels();
// Hadronic physics
//
@@ -188,34 +156,11 @@ void HadrontherapyPhysicsList::AddPhysicsList(const G4String& name)
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option4" << G4endl;
// The following 'local_ion_ion_inelastic' is an example of implemenation of
// inelastic hadronic models to be used when
// mucleus-nulceus (ion-ion) interactions have to be
// taken into account;
// It must be used, of course, in connection with other lists: electromagnetic
// plus hadronic elastic plus nucleon-nulcleon hadronic inelastic
//
// An example of coplete physics list using the 'local_ion_ion_inelastic' physics
// is the one named HADRONTHERAPY_2, and defined below.
//
} else if (name == "standard_opt3") {
emName = name;
delete emPhysicsList;
hadronPhys.clear();
emPhysicsList = new G4EmStandardPhysics_option3();
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option3" << G4endl;
} else if (name == "local_ion_ion_inelastic") {
hadronPhys.push_back(new LocalIonIonInelasticPhysic());
locIonIonInelasticIsRegistered = true;
////////////////////////////////////////
// ELECTROMAGNETIC + HADRONIC MODELS
////////////////////////////////////////
} else if (name == "HADRONTHERAPY_1") {
// The HADRONTHERAPY_1 physics list corresponds to the actual QGSP_BIC_HP list
// but with the following differences:
// --> G4EmStandardPhysics_option4 for the electromagnetic processes
// is used in place of the less accurate G4EmStandardPhysics
// --> The G4RadioactiveDecayPhysics is added
} else if (name == "HADRONTHERAPY_1") {
AddPhysicsList("standard_opt4");
hadronPhys.push_back( new G4DecayPhysics());
@@ -225,45 +170,25 @@ void HadrontherapyPhysicsList::AddPhysicsList(const G4String& name)
hadronPhys.push_back( new G4HadronElasticPhysicsHP());
hadronPhys.push_back( new G4StoppingPhysics());
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC_HP());
hadronPhys.push_back( new G4NeutronTrackingCut());
G4cout << "HADRONTHERAPY_1 PHYSICS LIST has been activated" << G4endl;
}
} else if (name == "HADRONTHERAPY_2") {
// The HADRONTHERAPY_2 physics list corresponds to the actual QGSP_BIC_HP list
// but with the following differences:
// --> G4EmStandardPhysics_option4 for the electromagnetic processes
// is used in place of the less accurate G4EmStandardPhysics
// --> The G4RadioactiveDecayPhysics is added
// --> The 'local_ion_ion_inelastic' physics is used in place of the
// G4IonBinaryCascadePhysics(): it used the QMD model to treat
// the ion-ion inelastic interactions
else if (name == "HADRONTHERAPY_2") {
// HP models are switched off
AddPhysicsList("standard_opt4");
AddPhysicsList("local_ion_ion_inelastic");
hadronPhys.push_back( new G4DecayPhysics());
hadronPhys.push_back( new G4RadioactiveDecayPhysics());
hadronPhys.push_back( new G4IonBinaryCascadePhysics());
hadronPhys.push_back( new G4EmExtraPhysics());
hadronPhys.push_back( new G4HadronElasticPhysicsHP());
hadronPhys.push_back( new G4HadronElasticPhysics());
hadronPhys.push_back( new G4StoppingPhysics());
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC_HP());
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC());
hadronPhys.push_back( new G4NeutronTrackingCut());
G4cout << "HADRONTHERAPY_2 PHYSICS LIST has been acivated" << G4endl;
}
else if (name == "QGSP_BIC_EMY") {
AddPhysicsList("standard_opt3");
//emPhysicsList = new G4EmLivermorePhysics();
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC());
hadronPhys.push_back( new G4EmExtraPhysics());
hadronPhys.push_back( new G4HadronElasticPhysics());
hadronPhys.push_back( new G4StoppingPhysics());
hadronPhys.push_back( new G4IonBinaryCascadePhysics());
hadronPhys.push_back( new G4NeutronTrackingCut());
hadronPhys.push_back( new G4DecayPhysics());
}
else {
G4cout << "HADRONTHERAPY_2 PHYSICS LIST has been activated" << G4endl; }
else {
G4cout << "PhysicsList::AddPhysicsList: <" << name << ">"
<< " is not defined"
<< G4endl;
@@ -274,52 +199,21 @@ void HadrontherapyPhysicsList::AddPhysicsList(const G4String& name)
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPhysicsList::AddStepMax()
{
// Step limitation seen as a process
// This process must exist in all threads.
//
HadrontherapyStepMax* stepMaxProcess = new HadrontherapyStepMax();
G4AutoDelete::Register( stepMaxProcess );
auto particleIterator=GetParticleIterator();
particleIterator->reset();
while ((*particleIterator)()){
G4ParticleDefinition* particle = particleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
if (stepMaxProcess->IsApplicable(*particle) && pmanager)
{
pmanager ->AddDiscreteProcess(stepMaxProcess);
}
}
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPhysicsList::SetCuts()
{
if (verboseLevel >0){
G4cout << "PhysicsList::SetCuts:";
G4cout << "CutLength : " << G4BestUnit(defaultCutValue,"Length") << G4endl;
}
// Step limitation seen as a process
// This process must exist in all threads.
//
HadrontherapyStepMax* stepMaxProcess = new HadrontherapyStepMax();
G4AutoDelete::Register( stepMaxProcess );
// Production thresholds for detector regions
// The G4Regions, for which you want define a given cut via de macro command
// '/run/setCutForRegion <G4Region name> <cut value>'
// must be defined here
//
SetCutValue(cutForGamma, "gamma");
SetCutValue(cutForElectron, "e-");
SetCutValue(cutForPositron, "e+");
// At moment, only 'DetectorLog' is defined as G4Region
//
G4String regName[] = {"DetectorLog"};
G4double fuc = 1.;
for(G4int i=0;i<1;i++)
{
G4Region* reg = G4RegionStore::GetInstance()->GetRegion(regName[i]);
G4ProductionCuts* cuts = new G4ProductionCuts;
cuts->SetProductionCut(defaultCutValue*fuc);
reg->SetProductionCuts(cuts);
fuc *= 10.;
auto particleIterator = GetParticleIterator();
particleIterator->reset();
while ((*particleIterator)()){
G4ParticleDefinition* particle = particleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
if (stepMaxProcess->IsApplicable(*particle) && pmanager)
{
pmanager ->AddDiscreteProcess(stepMaxProcess);
}
}
}
@@ -28,7 +28,9 @@
#include "HadrontherapyPrimaryGeneratorAction.hh"
#include "HadrontherapyPrimaryGeneratorMessenger.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "HadrontherapyMatrix.hh"
#include "HadrontherapyDetectorSD.hh"
#include "G4SystemOfUnits.hh"
#include "G4Event.hh"
#include "G4ParticleGun.hh"
@@ -36,36 +38,46 @@
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "Randomize.hh"
#include "G4IonTable.hh"
#include "G4VUserPrimaryGeneratorAction.hh"
#include "G4ParticleTable.hh"
#include "G4Event.hh"
#include "G4Timer.hh"
#include "G4RunManager.hh"
/////////////////////////////////////////////////////////////////////////////
HadrontherapyPrimaryGeneratorAction::HadrontherapyPrimaryGeneratorAction()
{
SetDefaultPrimaryParticle();
// Definition of the General particle Source
particleGun = new G4GeneralParticleSource();
}
PrimaryGeneratorMessenger = new HadrontherapyPrimaryGeneratorMessenger(this);
SetDefaultPrimaryParticle();
particleGun = new G4GeneralParticleSource();
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyPrimaryGeneratorAction::~HadrontherapyPrimaryGeneratorAction()
{
delete particleGun;
delete PrimaryGeneratorMessenger;
delete particleGun;
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPrimaryGeneratorAction::SetDefaultPrimaryParticle()
{
{
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
#ifdef G4ANALYSIS_USE_ROOT
// Increment the event counter
HadrontherapyAnalysisManager::GetInstance()->startNewEvent();
#endif
particleGun -> GeneratePrimaryVertex( anEvent );
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
particleGun->GeneratePrimaryVertex(anEvent);
}
@@ -32,138 +32,21 @@
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4SystemOfUnits.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithABool.hh"
HadrontherapyPrimaryGeneratorMessenger::HadrontherapyPrimaryGeneratorMessenger(
HadrontherapyPrimaryGeneratorAction* HadrontherapyGun)
:HadrontherapyAction(HadrontherapyGun)
{
//
// Definition of the interactive commands to modify the parameters of the
// generation of primary particles
//
beamParametersDir = new G4UIdirectory("/beam/");
beamParametersDir -> SetGuidance("set parameters of beam");
EnergyDir = new G4UIdirectory("/beam/energy/");
EnergyDir -> SetGuidance ("set energy of beam");
particlePositionDir = new G4UIdirectory("/beam/position/");
particlePositionDir -> SetGuidance ("set position of particle");
MomentumDir = new G4UIdirectory("/beam/momentum/");
MomentumDir -> SetGuidance ("set momentum of particle ");
/*
sigmaMomentumYCmd = new G4UIcmdWithADouble("/beam/momentum/sigmaY",this);
sigmaMomentumYCmd -> SetGuidance("set sigma momentum y");
sigmaMomentumYCmd -> SetParameterName("momentum",false);
sigmaMomentumYCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
sigmaMomentumZCmd = new G4UIcmdWithADouble("/beam/momentum/sigmaZ",this);
sigmaMomentumZCmd -> SetGuidance("set sigma momentum z");
sigmaMomentumZCmd -> SetParameterName("momentum",false);
sigmaMomentumZCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
meanKineticEnergyCmd = new G4UIcmdWithADoubleAndUnit("/beam/energy/meanEnergy",this);
meanKineticEnergyCmd -> SetGuidance("set mean Kinetic energy");
meanKineticEnergyCmd -> SetParameterName("Energy",false);
meanKineticEnergyCmd -> SetDefaultUnit("MeV");
meanKineticEnergyCmd -> SetUnitCandidates("eV keV MeV GeV TeV");
meanKineticEnergyCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
sigmaEnergyCmd = new G4UIcmdWithADoubleAndUnit("/beam/energy/sigmaEnergy",this);
sigmaEnergyCmd -> SetGuidance("set sigma energy");
sigmaEnergyCmd -> SetParameterName("Energy",false);
sigmaEnergyCmd -> SetDefaultUnit("keV");
sigmaEnergyCmd -> SetUnitCandidates("eV keV MeV GeV TeV");
sigmaEnergyCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
XpositionCmd = new G4UIcmdWithADoubleAndUnit("/beam/position/Xposition",this);
XpositionCmd -> SetGuidance("set x coordinate of particle");
XpositionCmd -> SetParameterName("position",false);
XpositionCmd -> SetDefaultUnit("mm");
XpositionCmd -> SetUnitCandidates("mm cm m");
XpositionCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
YpositionCmd = new G4UIcmdWithADoubleAndUnit("/beam/position/Yposition",this);
YpositionCmd -> SetGuidance("set y coordinate of particle");
YpositionCmd -> SetParameterName("position",false);
YpositionCmd -> SetDefaultUnit("mm");
YpositionCmd -> SetUnitCandidates("mm cm m");
YpositionCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
sigmaYCmd = new G4UIcmdWithADoubleAndUnit("/beam/position/Yposition/sigmaY",this);
sigmaYCmd -> SetGuidance("set sigma y");
sigmaYCmd -> SetParameterName("position",false);
sigmaYCmd -> SetDefaultUnit("mm");
sigmaYCmd -> SetUnitCandidates("mm cm m");
sigmaYCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
ZpositionCmd = new G4UIcmdWithADoubleAndUnit("/beam/position/Zposition",this);
ZpositionCmd -> SetGuidance("set z coordinate of particle");
ZpositionCmd -> SetParameterName("position",false);
ZpositionCmd -> SetDefaultUnit("mm");
ZpositionCmd -> SetUnitCandidates("mm cm m");
ZpositionCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
sigmaZCmd = new G4UIcmdWithADoubleAndUnit("/beam/position/Zposition/sigmaZ",this);
sigmaZCmd -> SetGuidance("set sigma z");
sigmaZCmd -> SetParameterName("position",false);
sigmaZCmd -> SetDefaultUnit("mm");
sigmaZCmd -> SetUnitCandidates("mm cm m");
sigmaZCmd -> AvailableForStates(G4State_PreInit,G4State_Idle);
*/
{
}
HadrontherapyPrimaryGeneratorMessenger::~HadrontherapyPrimaryGeneratorMessenger()
{
delete beamParametersDir;
delete EnergyDir;
// delete meanKineticEnergyCmd;
// delete sigmaEnergyCmd;
delete particlePositionDir;
delete MomentumDir;
/* delete XpositionCmd;
delete YpositionCmd;
delete ZpositionCmd;
delete sigmaYCmd;
delete sigmaZCmd;
delete sigmaMomentumYCmd;
delete sigmaMomentumZCmd; */
}
/*
void HadrontherapyPrimaryGeneratorMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if ( command == meanKineticEnergyCmd )
{ HadrontherapyAction -> SetmeanKineticEnergy(meanKineticEnergyCmd
-> GetNewDoubleValue(newValue));}
if ( command == sigmaEnergyCmd )
{ HadrontherapyAction -> SetsigmaEnergy(sigmaEnergyCmd
-> GetNewDoubleValue(newValue));}
if ( command == XpositionCmd )
{ HadrontherapyAction -> SetXposition(XpositionCmd
-> GetNewDoubleValue(newValue));}
if ( command == YpositionCmd )
{ HadrontherapyAction -> SetYposition(YpositionCmd
-> GetNewDoubleValue(newValue));}
}
if ( command == ZpositionCmd )
{ HadrontherapyAction -> SetZposition(ZpositionCmd
-> GetNewDoubleValue(newValue));}
if ( command == sigmaYCmd )
{ HadrontherapyAction -> SetsigmaY(sigmaYCmd
-> GetNewDoubleValue(newValue));}
if ( command == sigmaZCmd )
{ HadrontherapyAction -> SetsigmaZ(sigmaZCmd
-> GetNewDoubleValue(newValue));}
if ( command == sigmaMomentumYCmd )
{ HadrontherapyAction -> SetsigmaMomentumY(sigmaMomentumYCmd
-> GetNewDoubleValue(newValue));}
if ( command == sigmaMomentumZCmd )
{ HadrontherapyAction -> SetsigmaMomentumZ(sigmaMomentumZCmd
-> GetNewDoubleValue(newValue));}
} */
@@ -37,27 +37,31 @@
#include "G4Timer.hh"
#include "HadrontherapyRunAction.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "HadrontherapyMatrix.hh"
HadrontherapyRunAction::HadrontherapyRunAction()
{
}
HadrontherapyRunAction::~HadrontherapyRunAction()
{
{
}
void HadrontherapyRunAction::BeginOfRunAction(const G4Run* aRun)
{
{
G4RunManager::GetRunManager()-> SetRandomNumberStore(true);
G4cout << "Run " << aRun -> GetRunID() << " starts ..." << G4endl;
electromagnetic = 0;
hadronic = 0;
}
void HadrontherapyRunAction::EndOfRunAction(const G4Run*)
@@ -70,10 +74,10 @@ void HadrontherapyRunAction::EndOfRunAction(const G4Run*)
}
void HadrontherapyRunAction::AddEMProcess()
{
electromagnetic += 1;
electromagnetic += 1;
}
void HadrontherapyRunAction::AddHadronicProcess()
{
hadronic += 1;
hadronic += 1;
}
@@ -42,7 +42,7 @@
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "HadrontherapyRunAction.hh"
#include "HadrontherapyAnalysisManager.hh"
#include "HadrontherapyMatrix.hh"
#include "G4SystemOfUnits.hh"
/////////////////////////////////////////////////////////////////////////////
@@ -59,631 +59,63 @@ HadrontherapySteppingAction::~HadrontherapySteppingAction()
/////////////////////////////////////////////////////////////////////////////
void HadrontherapySteppingAction::UserSteppingAction(const G4Step* aStep)
{
G4StepPoint* PreStep = aStep->GetPreStepPoint();
G4StepPoint* PostStep = aStep->GetPostStepPoint();
G4double PreStepX =PreStep->GetPosition().x();
G4double PreStepY =PreStep->GetPosition().y();
G4double PreStepZ =PreStep->GetPosition().z();
G4double parentID =aStep->GetTrack()->GetParentID();
G4double trackID =aStep->GetTrack()->GetTrackID();
G4double PostStepX =PostStep->GetPosition().x();
G4double PostStepY =PostStep->GetPosition().y();
G4double PostStepZ =PostStep->GetPosition().z();
// positions in the global coordinate system:
//G4ThreeVector posPreStep = PreStep->GetPosition();
// G4ThreeVector posPostStep = PostStep->GetPosition();
G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
G4TouchableHandle touchPostStep = PostStep->GetTouchableHandle();
//To get the current volume:
G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
G4VPhysicalVolume* volumePost =touchPostStep->GetVolume();
//To get its name:
G4String namePre = volumePre->GetName();
G4String namePost;
if(volumePost){
namePost = volumePost->GetName();
}
G4int eventNum = G4RunManager::GetRunManager() -> GetCurrentEvent() -> GetEventID();
G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
G4double PosX = aStep->GetTrack()->GetPosition().x();
G4double PosY = aStep->GetTrack()->GetPosition().y();
G4double PosZ = aStep->GetTrack()->GetPosition().z();
G4String material= aStep -> GetTrack() -> GetMaterial() -> GetName();
G4String volume= aStep->GetTrack()->GetVolume()->GetName();
G4Track* theTrack = aStep->GetTrack();
if((namePre== "collimator")||(namePre== "PhysicExternalMagnet_1Down")||(namePre== "PhysicExternalMagnet_1")||(namePre== "PhysicMagnet_1Right")||(namePre== "PhysicMagnet_1Left")||(namePre== "PhysicExternalMagnet_2")||(namePre== "PhysicExternalMagnet_2Down")||(namePre== "PhysicMagnet_2Right")||(namePre== "PhysicMagnet_2Left")||(namePre== "PhysicExternalMagnet_3")||(namePre== "PhysicExternalMagnet_3Down")||(namePre== "PhysicMagnet_3Right")||(namePre== "PhysicMagnet_3Left")||(namePre== "PhysicExternalMagnet_4")||(namePre== "PhysicExternalMagnet_4Down")||(namePre=="physQuadChamberWall")||(namePre== "PhysicMagnet_4Right")||(namePre== "PhysicMagnet_4Left")||(namePre=="ExternalChamber")||(namePre=="collimatorFinal")||(namePre=="ExternalSlit")||(namePre=="PhysFourthQuad")||(namePre=="PhysThirdQuad")||(namePre=="PhysSecondQuad")||(namePre=="PhysFirstQuad"))
{
theTrack -> SetTrackStatus(fKillTrackAndSecondaries);
}
// G4TransportationManager* tManager = G4TransportationManager::GetTransportationManager();
//G4VPhysicalVolume* pW = tManager->GetParallelWorld ("DetectorROGeometry");
//G4Navigator* gNav = tManager->GetNavigator(pW);
// G4VPhysicalVolume* currentVol = gNav->LocateGlobalPointAndSetup(aStep->GetTrack()->GetPosition());
// G4cout << "Step: " << currentVol->GetName() << " " << aStep->GetTrack()->GetPosition() << G4endl;
//G4cout << "G4LogicalVolume: = " << currentVol->GetLogicalVolume()->GetName() << G4endl;
//if (currentVol->GetLogicalVolume()->GetSensitiveDetector())
// G4cout << "Sensitive Detector: " << currentVol->GetLogicalVolume()->GetSensitiveDetector()->GetName() << G4endl;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// A METHOD TO RETRIEVE INFORMATIONS ABOUT SECONDARY ELECTRONS IN DIFFERENT POINTS OF FARADAY CUP ////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The followings are calls to usefuls information retrieved at the step level
// Please, comment out them if want to use
// G4Track* theTrack = aStep->GetTrack();
//G4StepPoint* PreStep = aStep->GetPreStepPoint();
//G4StepPoint* PostStep = aStep->GetPostStepPoint();
//G4TouchableHandle touchPreStep = PreStep->GetTouchableHandle();
//G4TouchableHandle touchPostStep = PostStep->GetTouchableHandle();
//G4double PreStepX =PreStep->GetPosition().x();
//G4double PreStepY =PreStep->GetPosition().y();
//G4double PreStepZ =PreStep->GetPosition().z();
//G4double PostStepX =PostStep->GetPosition().x();
//G4double PostStepY =PostStep->GetPosition().y();
//G4double PostStepZ =PostStep->GetPosition().z();
//if( (aStep->GetTLocateGlobalPointAndSeturack()->GetVolume()->GetName() == "PVirtualMag")
if((aStep->GetTrack()->GetVolume()->GetName()=="PVirtualMag") && aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-")
{
std::ofstream WriteDataIn("new200.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PosX << '\t' << " "
<< PosY << '\t' << " "
<< PosZ << '\t' << " "
//<< material << '\t' << " "
// << volume << '\t' << " "
<< G4endl;
}
// USEFULL METHODS TO RETRIEVE INFORMATION DURING THE STEPS
/* G4cout << "ENERGIA: " << aStep->GetTrack()->GetKineticEnergy()
<< " VOLUME " << aStep->GetTrack()->GetVolume()->GetName()
<< " MATERIALE " << aStep -> GetTrack() -> GetMaterial() -> GetName()
<< " EVENTO " << G4RunManager::GetRunManager()->GetCurrentEvent() -> GetEventID()
<< " POS " << aStep->GetTrack()->GetPosition().x()
<< G4endl;*/
//To get the current volume:
//G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
//G4VPhysicalVolume* volumePost =touchPostStep->GetVolume();
if ((namePre=="PhysicEntranceWindow") &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary))
{
std::ofstream WriteDataIn("finestra.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
//To get its name:
//G4String namePre = volumePre->GetName();
//theTrack -> SetTrackStatus(fKillTrackAndSecondaries);
}
if ((namePre=="PhysicCup") && (aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary))
{
std::ofstream WriteDataBack("fondo.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
//theTrack -> SetTrackStatus(fKillTrackAndSecondaries);
}
//////////////////////////////////// VIRTUAL WINDOW //////////////////////////////////////////////////
if (((namePost=="PhysicVirtualWindow") && (namePre!="PhysicVirtualWindow")) &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary)) //To check that the particle has just entered in the current volume (i.e. it is at the first step in the volume; the preStepPoint is at the boundary):
{ //(namePost=="VirtualWindow") &&
if ((PostStepX - PreStepX)>0)
{
//To check that the particle is leaving the current volume (i.e. it is at the last step in the volume; the postStepPoint is at the boundary):
// if (PostStep->GetStepStatus() == fGeomBoundary)
std::ofstream WriteDataIn("DatiFCWindowIn.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
//<< direction.x() << '\t' << " "
//<< direction.y() << '\t' << " "
//<< direction.z() << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
// positions in the global coordinate system:
//G4ThreeVector posPreStep = PreStep->GetPosition();
//G4ThreeVector posPostStep = PostStep->GetPosition();
else //if ((PostStepX - PreStepX)<0)
{
//G4cout<<"ecco il nome del volume nella condizione Out "<< namePre<<" "<<namePost<<G4endl;
std::ofstream WriteDataBack("DatiFCWindowBack.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
}
///////////////////////////////////////// proton in window //////////////////////////////////////////////////
/*
if ((namePost=="SpectrumPVolume") && (namePre!="SpectrumPVolume") &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton"))//&& (PreStep->GetStepStatus() == fGeomBoundary)To check that the particle has just entered in the current volume (i.e. it is at the first step in the volume; the preStepPoint is at the boundary):
{ //(namePost=="VirtualVolumeWindow") &&
//G4int eventNum = G4RunManager::GetRunManager() -> GetCurrentEvent() -> GetEventID();
//To check that the particle is leaving the current volume (i.e. it is at the last step in the volume; the postStepPoint is at the boundary):
// if (PostStep->GetStepStatus() == fGeomBoundary)
*/
/*
std::ofstream WriteDataP("DatiFCWindowProton.out", std::ios::app);
WriteDataP << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
*/
if (((namePost=="PhysicVirtualWindow") && (namePre!="PhysicVirtualWindow")) &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton"))//&& (PreStep->GetStepStatus() == fGeomBoundary)) //To check that the particle has just entered in the current volume (i.e. it is at the first step in the volume; the preStepPoint is at the boundary):
{ //(namePost=="VirtualVolumeWindow") &&
//G4double parentID =aStep->GetTrack()->GetParentID();
//G4double trackID =aStep->GetTrack()->GetTrackID();
//To check that the particle is leaving the current volume (i.e. it is at the last step in the volume; the postStepPoint is at the boundary):
// if (PostStep->GetStepStatus() == fGeomBoundary)
//
std::ofstream WriteData("DatiFCAfterWindowProton.out", std::ios::app);
WriteData << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
////////////////////////////////////////////////// GUARD RING ///////////////////////////////////////////////////////////////
//G4double eKin = aStep -> GetPreStepPoint() -> GetKineticEnergy();
if ((namePre=="PhysicGuardRing") &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-")&& (PreStep->GetStepStatus() == fGeomBoundary))
{
if ((PostStepX - PreStepX)>0)
{
std::ofstream WriteDataIn("DatiFCGuardRingIn.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< G4endl;
}
//G4double PosX = aStep->GetTrack()->GetPosition().x();
//G4double PosY = aStep->GetTrack()->GetPosition().y();
//G4double PosZ = aStep->GetTrack()->GetPosition().z();
else
{
std::ofstream WriteDataBack("DatiFCGuardRingBack.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< G4endl;
}
}
//////////////////////////////////////// VIRTUAL MIDDLE ///////////////////////////////////////////////////////////////
//G4String material= aStep -> GetTrack() -> GetMaterial() -> GetName();
//G4cout << "material " << material << G4endl;
if (((namePost=="PhysicVirtualMiddle") && (namePre!="PhysicVirtualMiddle")) &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary))
{
if ((PostStepX - PreStepX)>0)
{
//
std::ofstream WriteMDataIn("DatiFCMiddleIn.out", std::ios::app);
WriteMDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
//G4String volume= aStep->GetTrack()->GetVolume()->GetName();
else
{
std::ofstream WriteMDataBack("DatiFCMiddleBack.out", std::ios::app);
WriteMDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
}
/////////////////////////////////////// VIRTUAL BOTTOM ///////////////////////////////////////////////////////////////
if (((namePost=="PhysicVirtualBottom") && (namePre!="PhysicVirtualBottom")) &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-")&& (PreStep->GetStepStatus() == fGeomBoundary))
{
if ((PostStepX - PreStepX)>0)
{
std::ofstream WriteDataIn("DatiFCBottomIn.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
else
{
//G4cout<<"ecco il nome del volume nella condizione Back "<< namePre<<" "<<namePost<<G4endl;
std::ofstream WriteDataBack("DatiFCBottomBack.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
//<< direction.x() << '\t' << " "
//<< direction.y() << '\t' << " "
//<< direction.z() << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
}
////////////////////////////////////////////////// Dose Calculation ///////////////////////////////////////////////////////////////
//namePre!=("Cup")
if (((namePost=="PhysicCup") && (namePre!="PhysicCup")) &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton") && (PreStep->GetStepStatus() == fGeomBoundary)) //|| (namePre=="Cup") && )
{
std::ofstream Carica("CaricaRaccolta.out", std::ios::app);
Carica << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
//namePre!=("PhysicFaradayCupBottom")
if (((namePost=="PhysicFaradayCupBottom") && (namePre!="PhysicFaradayCupBottom"))&&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton") && (PreStep->GetStepStatus() == fGeomBoundary)) // || (namePre=="cup") && )
{
std::ofstream CaricaLatFC("CaricaRaccoltaLatFC.out", std::ios::app);
CaricaLatFC << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
if (((namePre=="PhysicFaradayCupBottom") || (namePre=="PhysicCup")) && ((aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary)))
{
if ((PostStepX - PreStepX)>0)
{
std::ofstream WriteDataIn("DatiFCConeBottomCupIn.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< G4endl;
}
//G4String pvname= pv-> GetName();
else
{
//G4cout<<"ecco il nome del volume nella condizione Back "<< namePre<<" "<<namePost<<G4endl;
std::ofstream WriteDataBack("DatiFCConeBottomCupBack.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< G4endl;
}
}
G4String particleName = aStep->GetTrack()->GetDefinition()->GetParticleName();
///////////////////////////////////////////////// VIRTUAL OVER BOTTOM ///////////////////////////////////////////////////////////////
if ((namePre=="PhysicVirtualOverBottom") &&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-")&& (PreStep->GetStepStatus() == fGeomBoundary))
{
if ((PostStepX - PreStepX)>0)
{
//
std::ofstream WriteDataIn("DatiFCOverBottomIn.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
else
{
//G4cout<<"ecco il nome del volume nella condizione Back "<< namePre<<" "<<namePost<<G4endl;
std::ofstream WriteDataBack("DatiFCOverBottomBack.out", std::ios::app);
WriteDataBack << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PreStepX << '\t' << " "
<< PreStepY << '\t' << " "
<< PreStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
}
///////////////////////////////////////////// VIRTUAL LATERAL ///////////////////////////////////////////////////////////////
if (((namePost=="PhysicVirtualLateral") && (namePre!="PhysicVirtualLateral"))&&
(aStep->GetTrack()->GetDefinition()->GetParticleName() == "e-") && (PreStep->GetStepStatus() == fGeomBoundary))
{
std::ofstream WriteDataIn("DatiFCLateral.out", std::ios::app);
WriteDataIn << eKin << '\t' << " "
<< eventNum << '\t' << " "
<< PostStepX << '\t' << " "
<< PostStepY << '\t' << " "
<< PostStepZ << '\t' << " "
<< parentID << '\t' << " "
<< trackID << '\t' << " "
<< G4endl;
}
if( aStep->GetTrack()->GetVolume()->GetName() == "NewDetectorPhys"){
#ifdef G4ANALYSIS_USE_ROOT
G4ParticleDefinition *def = aStep->GetTrack()->GetDefinition();
G4double secondaryParticleKineticEnergy = aStep->GetTrack()->GetKineticEnergy();
G4String particleType = def->GetParticleType(); // particle type = nucleus for d, t, He3, alpha, and heavier nuclei
G4String particleName = def->GetParticleName(); // e.g. for alpha: the name = "alpha" and type = "nucleus"
if(particleType == "nucleus") {
G4int A = def->GetBaryonNumber();
G4double Z = def->GetPDGCharge();
G4double posX = aStep->GetTrack()->GetPosition().x() / cm;
G4double posY = aStep->GetTrack()->GetPosition().y() / cm;
G4double posZ = aStep->GetTrack()->GetPosition().z() / cm;
G4double energy = secondaryParticleKineticEnergy / A / MeV;
HadrontherapyAnalysisManager* analysisMgr = HadrontherapyAnalysisManager::GetInstance();
analysisMgr->FillFragmentTuple(A, Z, energy, posX, posY, posZ);
} else if(particleName == "proton") { // proton (hydrogen-1) is a special case
G4double posX = aStep->GetTrack()->GetPosition().x() / cm ;
G4double posY = aStep->GetTrack()->GetPosition().y() / cm ;
G4double posZ = aStep->GetTrack()->GetPosition().z() / cm ;
G4double energy = secondaryParticleKineticEnergy * MeV; // Hydrogen-1: A = 1, Z = 1
HadrontherapyAnalysisManager::GetInstance()->FillFragmentTuple(1, 1.0, energy, posX, posY, posZ);
}
G4String secondaryParticleName = def -> GetParticleName();
//G4cout <<"Particle: " << secondaryParticleName << G4endl;
//G4cout <<"Energy: " << secondaryParticleKineticEnergy << G4endl;
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
//There is a bunch of stuff recorded with the energy 0, something should perhaps be done about this.
if(secondaryParticleName == "proton") {
analysis->hydrogenEnergy(secondaryParticleKineticEnergy / MeV);
}
if(secondaryParticleName == "deuteron") {
analysis->hydrogenEnergy((secondaryParticleKineticEnergy/2) / MeV);
}
if(secondaryParticleName == "triton") {
analysis->hydrogenEnergy((secondaryParticleKineticEnergy/3) / MeV);
}
if(secondaryParticleName == "alpha") {
analysis->heliumEnergy((secondaryParticleKineticEnergy/4) / MeV);
}
if(secondaryParticleName == "He3"){
analysis->heliumEnergy((secondaryParticleKineticEnergy/3) / MeV);
}
#endif
aStep->GetTrack()->SetTrackStatus(fKillTrackAndSecondaries);
}
// Electromagnetic and hadronic processes of primary particles in the phantom
//setting phantomPhys correctly will break something here fixme
if ((aStep -> GetTrack() -> GetTrackID() == 1) &&
(aStep -> GetTrack() -> GetVolume() -> GetName() == "PhantomPhys") &&
(aStep -> GetPostStepPoint() -> GetProcessDefinedStep() != NULL))
{
G4String process = aStep -> GetPostStepPoint() ->
GetProcessDefinedStep() -> GetProcessName();
if ((process == "Transportation") || (process == "StepLimiter")) {;}
else
{
if ((process == "msc") || (process == "hLowEIoni") || (process == "hIoni"))
{
runAction -> AddEMProcess();
}
else
{
runAction -> AddHadronicProcess();
if ( (process != "LElastic") && (process != "ProtonInelastic") && (process != "hElastic") )
G4cout << "Warning! Unknown proton process: "<< process << G4endl;
}
}
}
// Retrieve information about the secondary particles originated in the phantom
G4SteppingManager* steppingManager = fpSteppingManager;
// check if it is alive
//if(theTrack-> GetTrackStatus() == fAlive) { return; }
// Retrieve the secondary particles
G4TrackVector* fSecondary = steppingManager -> GetfSecondary();
for(size_t lp1=0;lp1<(*fSecondary).size(); lp1++)
{
G4String volumeName = (*fSecondary)[lp1] -> GetVolume() -> GetName();
if (volumeName == "phantomPhys")
{
#ifdef G4ANALYSIS_USE_ROOT
G4String secondaryParticleName = (*fSecondary)[lp1]->GetDefinition() -> GetParticleName();
G4double secondaryParticleKineticEnergy = (*fSecondary)[lp1] -> GetKineticEnergy();
HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance();
if (secondaryParticleName == "e-")
analysis -> electronEnergyDistribution(secondaryParticleKineticEnergy/MeV);
if (secondaryParticleName == "gamma")
analysis -> gammaEnergyDistribution(secondaryParticleKineticEnergy/MeV);
if (secondaryParticleName == "deuteron")
analysis -> deuteronEnergyDistribution(secondaryParticleKineticEnergy/MeV);
if (secondaryParticleName == "triton")
analysis -> tritonEnergyDistribution(secondaryParticleKineticEnergy/MeV);
if (secondaryParticleName == "alpha")
analysis -> alphaEnergyDistribution(secondaryParticleKineticEnergy/MeV);
G4double z = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetPDGCharge();
if (z > 0.)
{
G4int a = (*fSecondary)[lp1]-> GetDynamicParticle() -> GetDefinition() -> GetBaryonNumber();
G4int electronOccupancy = (*fSecondary)[lp1] -> GetDynamicParticle() -> GetTotalOccupancy();
// If a generic ion is originated in the detector, its baryonic number, PDG charge,
// total number of electrons in the orbitals are stored in a ntuple
analysis -> genericIonInformation(a, z, electronOccupancy, secondaryParticleKineticEnergy/MeV);
}
#endif
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,101 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Hadrontherapy advanced example for Geant4
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
#include "PassiveCarbonBeamLineMessenger.hh"
#include "PassiveCarbonBeamLine.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4SystemOfUnits.hh"
PassiveCarbonBeamLineMessenger::PassiveCarbonBeamLineMessenger(PassiveCarbonBeamLine* beamLine)
:passiveCarbon(beamLine)
{
beamLineDir = new G4UIdirectory("/beamLine/");
beamLineDir -> SetGuidance("set specification of ripple filter");
RippleFilterDir = new G4UIdirectory("/beamLine/RippleFilter/");
RippleFilterDir -> SetGuidance("set specification of ripple filter");
finalCollimatorDir = new G4UIdirectory("/beamLine/FinalCollimator/");
finalCollimatorDir -> SetGuidance("set specification of final collimator");
RippleFilterMatCmd = new G4UIcmdWithAString("/beamLine/RippleFilter/RFMat",this);
RippleFilterMatCmd -> SetGuidance("Set material of ripple filter");
RippleFilterMatCmd -> SetParameterName("choice",false);
RippleFilterMatCmd -> AvailableForStates(G4State_Idle);
RippleFilterXPositionCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/RippleFilter/position",this);
RippleFilterXPositionCmd -> SetGuidance("Set position of ripple filter");
RippleFilterXPositionCmd -> SetParameterName("Size",false);
RippleFilterXPositionCmd -> SetDefaultUnit("mm");
RippleFilterXPositionCmd -> SetUnitCandidates("mm cm m");
RippleFilterXPositionCmd -> AvailableForStates(G4State_Idle);
innerRadiusFinalCollimatorCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/FinalCollimator/halfInnerRad",this);
innerRadiusFinalCollimatorCmd -> SetGuidance("Set size of inner radius ( max 21.5 mm)");
innerRadiusFinalCollimatorCmd -> SetParameterName("Size",false);
innerRadiusFinalCollimatorCmd -> SetDefaultUnit("mm");
innerRadiusFinalCollimatorCmd -> SetUnitCandidates("mm cm m");
innerRadiusFinalCollimatorCmd -> AvailableForStates(G4State_Idle);
}
PassiveCarbonBeamLineMessenger::~PassiveCarbonBeamLineMessenger()
{
delete innerRadiusFinalCollimatorCmd;
delete RippleFilterXPositionCmd;
delete RippleFilterMatCmd;
delete finalCollimatorDir;
delete RippleFilterDir;
delete beamLineDir;
}
void PassiveCarbonBeamLineMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == RippleFilterMatCmd )
{ passiveCarbon -> SetRippleFilterMaterial(newValue);
}
else if( command == RippleFilterXPositionCmd )
{ passiveCarbon -> SetRippleFilterXPosition
(RippleFilterXPositionCmd -> GetNewDoubleValue(newValue));
}
else if( command == innerRadiusFinalCollimatorCmd )
{ passiveCarbon -> SetInnerRadiusFinalCollimator
(innerRadiusFinalCollimatorCmd -> GetNewDoubleValue(newValue));
}
}
@@ -42,7 +42,7 @@
#include "HadrontherapyModulator.hh"
#include "PassiveProtonBeamLine.hh"
#include "PassiveProtonBeamLineMessenger.hh"
//#include "FaradayCup.hh"
//G4bool PassiveProtonBeamLine::doCalculation = false;
/////////////////////////////////////////////////////////////////////////////
@@ -57,8 +57,7 @@ physiHoleFirstCollimatorModulatorBox(0), physiSecondCollimatorModulatorBox(0),
physiHoleSecondCollimatorModulatorBox(0), physiMOPIMotherVolume(0),
physiFirstMonitorLayer1(0), physiFirstMonitorLayer2(0), physiFirstMonitorLayer3(0),
physiFirstMonitorLayer4(0), physiSecondMonitorLayer1(0), physiSecondMonitorLayer2(0),
physiSecondMonitorLayer3(0), physiSecondMonitorLayer4(0), physiNozzleSupport(0), //physiHoleNozzleSupport(0),
physiBrassTube(0), solidFinalCollimator(0), physiFinalCollimator(0)
physiSecondMonitorLayer3(0), physiSecondMonitorLayer4(0), physiNozzleSupport(0), physiBrassTube(0), solidFinalCollimator(0), physiFinalCollimator(0)
{
// Messenger to change parameters of the passiveProtonBeamLine geometry
passiveMessenger = new PassiveProtonBeamLineMessenger(this);
@@ -70,22 +69,14 @@ physiBrassTube(0), solidFinalCollimator(0), physiFinalCollimator(0)
G4cout << "Going to register Parallel world...";
RegisterParallelWorld(RO);
G4cout << "... done" << G4endl;
//***************************** PW ***************************************
/* // For the Faraday Cup activation
if (name)
{
doCalculation = true;
}*/
}
/////////////////////////////////////////////////////////////////////////////
PassiveProtonBeamLine::~PassiveProtonBeamLine()
{
delete passiveMessenger;
delete hadrontherapyDetectorConstruction;
/* if (!pFaradayCup)
{
delete pFaradayCup;
}*/
}
/////////////////////////////////////////////////////////////////////////////
@@ -111,11 +102,7 @@ G4VPhysicalVolume* PassiveProtonBeamLine::Construct()
hadrontherapyDetectorConstruction->InitializeDetectorROGeometry(RO,hadrontherapyDetectorConstruction->GetDetectorToWorldPosition());
//***************************** PW ***************************************
/* if (doCalculation)
{
pFaradayCup = new FaradayCup(physicalTreatmentRoom);
G4cout << "Faraday Cup detector has been activated" << G4endl;
}*/
return physicalTreatmentRoom;
}
@@ -604,7 +591,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamLineSupport()
const G4double beamLineSupportYPosition = -230. *mm;
const G4double beamLineSupportZPosition = 0.*mm;
G4Box* beamLineSupport = new G4Box("BeamLineSupport",
G4Box* beamLineSupport = new G4Box("BeamLineSupport",
beamLineSupportXSize,
beamLineSupportYSize,
beamLineSupportZSize);
@@ -622,7 +609,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamLineSupport()
// Visualisation attributes of the beam line support
logicBeamLineSupport -> SetVisAttributes(gray);
//---------------------------------//
// Beam line cover 1 (left panel) //
//---------------------------------//
@@ -634,7 +621,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamLineSupport()
const G4double beamLineCoverYPosition = -1000.*mm;
const G4double beamLineCoverZPosition = 600.*mm;
G4Box* beamLineCover = new G4Box("BeamLineCover",
G4Box* beamLineCover = new G4Box("BeamLineCover",
beamLineCoverXSize,
beamLineCoverYSize,
beamLineCoverZSize);
@@ -666,12 +653,13 @@ void PassiveProtonBeamLine::HadrontherapyBeamLineSupport()
0);
logicBeamLineCover -> SetVisAttributes(blue);
}
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyBeamScatteringFoils()
{
// ------------//
// ------------//
// VACUUM PIPE //
//-------------//
//
@@ -704,6 +692,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamScatteringFoils()
// THE KAPTON WINDOWS //
//--------------------//
//It prmits the passage of the beam from vacuum to air
G4Box* solidKaptonWindow = new G4Box("KaptonWindow",
kaptonWindowXSize,
kaptonWindowYSize,
@@ -779,6 +768,8 @@ void PassiveProtonBeamLine::HadrontherapyBeamScatteringFoils()
0);
logicSecondScatteringFoil -> SetVisAttributes(skyBlue);
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyRangeShifter()
@@ -788,6 +779,8 @@ void PassiveProtonBeamLine::HadrontherapyRangeShifter()
// -----------------------------//
// It is a slab of PMMA acting as energy degreader of
// primary beam
solidRangeShifterBox = new G4Box("RangeShifterBox",
rangeShifterXSize,
rangeShifterYSize,
@@ -806,10 +799,14 @@ void PassiveProtonBeamLine::HadrontherapyRangeShifter()
logicRangeShifterBox -> SetVisAttributes(yellow);
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyBeamCollimators()
{
// -----------------//
// FIRST COLLIMATOR //
// -----------------//
@@ -822,6 +819,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamCollimators()
const G4double firstCollimatorYPosition = 0.*mm;
const G4double firstCollimatorZPosition = 0.*mm;
G4Box* solidFirstCollimator = new G4Box("FirstCollimator",
firstCollimatorXSize,
firstCollimatorYSize,
@@ -914,7 +912,7 @@ void PassiveProtonBeamLine::HadrontherapyBeamCollimators()
const G4double firstCollimatorModulatorYPosition = 0.*mm;
const G4double firstCollimatorModulatorZPosition = 0.*mm;
G4Box* solidFirstCollimatorModulatorBox = new G4Box("FirstCollimatorModulatorBox",
G4Box* solidFirstCollimatorModulatorBox = new G4Box("FirstCollimatorModulatorBox",
firstCollimatorModulatorXSize,
firstCollimatorModulatorYSize,
firstCollimatorModulatorZSize);
@@ -1013,7 +1011,10 @@ void PassiveProtonBeamLine::HadrontherapyBeamCollimators()
logicFirstCollimator -> SetVisAttributes(yellow);
logicFirstCollimatorModulatorBox -> SetVisAttributes(blue);
logicSecondCollimatorModulatorBox -> SetVisAttributes(blue);
}
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyBeamMonitoring()
@@ -1036,7 +1037,9 @@ void PassiveProtonBeamLine::HadrontherapyBeamMonitoring()
const G4double monitor1XPosition = -1262.47498 *mm;
const G4double monitor2XPosition = -4.500011*mm;
const G4double monitor4XPosition = 4.500011*mm;
G4Box* solidFirstMonitorLayer1 = new G4Box("FirstMonitorLayer1",
monitor1XSize,
monitorYSize,
@@ -1117,10 +1120,13 @@ void PassiveProtonBeamLine::HadrontherapyBeamMonitoring()
logicFirstMonitorLayer3 -> SetVisAttributes(white);
}
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyMOPIDetector()
{
// --------------------------------//
// THE MOPI DETECTOR //
// --------------------------------//
@@ -1292,7 +1298,8 @@ void PassiveProtonBeamLine::HadrontherapyMOPIDetector()
logicMOPIFirstAirGap -> SetVisAttributes(darkGreen);
logicMOPISecondAirGap -> SetVisAttributes(darkGreen);
}
}
/////////////////////////////////////////////////////////////////////////////
void PassiveProtonBeamLine::HadrontherapyBeamNozzle()
{
@@ -1370,7 +1377,6 @@ void PassiveProtonBeamLine::HadrontherapyBeamNozzle()
logicHoleNozzleSupport -> SetVisAttributes(darkOrange3);
// ---------------------------------//
// BRASS TUBE 1 (phantom side) //
// ---------------------------------//
@@ -1405,7 +1411,6 @@ void PassiveProtonBeamLine::HadrontherapyBeamNozzle()
0);
logicBrassTube -> SetVisAttributes(darkOrange3);
// ----------------------------------------------//
// BRASS TUBE 2 (inside the PMMA support) //
@@ -1416,7 +1421,6 @@ void PassiveProtonBeamLine::HadrontherapyBeamNozzle()
const G4double startAngleBrassTube2 = 0.*deg;
const G4double spanningAngleBrassTube2 = 360.*deg;
// const G4double brassTube2XPosition = -227.5 *mm;
G4Tubs* solidBrassTube2 = new G4Tubs("BrassTube2",
innerRadiusBrassTube2,
@@ -1429,21 +1433,18 @@ void PassiveProtonBeamLine::HadrontherapyBeamNozzle()
brassTube2Material,
"BrassTube2",
0, 0, 0);
G4bool checkOverlaps = true;
new G4PVPlacement(0,
G4ThreeVector(),
logicBrassTube2,
"BrassTube2",
logicHoleNozzleSupport,
false,
0,
checkOverlaps);
physiBrassTube2 = new G4PVPlacement(0,
G4ThreeVector(0,0.,0.),
logicBrassTube2,
"BrassTube2",
logicHoleNozzleSupport,
false,
0);
logicBrassTube2 -> SetVisAttributes(darkOrange3);
// --------------------------------------//
// BRASS TUBE 3 (beam line side) //
// -------------------------------------//
@@ -0,0 +1,953 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Hadrontherapy advanced example for Geant4
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4Box.hh"
#include "G4Tubs.hh"
#include "G4UnionSolid.hh"
#include "G4Trd.hh"
#include "G4AssemblyVolume.hh"
#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4RunManager.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVReplica.hh"
#include "G4RotationMatrix.hh"
#include "G4NistManager.hh"
#include "G4NistElementBuilder.hh"
#include "HadrontherapyDetectorConstruction.hh"
#include "TrentoPassiveProtonBeamLine.hh"
#include "TrentoPassiveProtonBeamLineMessenger.hh"
/////////////////////////////////////////////////////////////////////////////
TrentoPassiveProtonBeamLine::TrentoPassiveProtonBeamLine():
logicTreatmentRoom(0), physicalTreatmentRoom(0),hadrontherapyDetectorConstruction(0),
physiBeamLineSupport(0), physiBeamLineCover(0), physiBeamLineCover2(0),
physiMonitorLayer1(0), physiMonitorLayer2(0),
ScatteringFoil(0), logicScatteringFoil(0), physiScatteringFoil(0), ridgeFilterPhys(0), preCollimator(0), physiPreCollimator(0), Collimator(0), physiCollimator(0), solidAirTube(0), solidAirPreTube(0), physiAirTube(0), physiAirPreTube(0)
{
// Messenger to change parameters of the passiveTrentoBeamLine geometry
TrentoPassiveMessenger = new TrentoPassiveProtonBeamLineMessenger(this);
//***************************** PW ***********************************
static G4String ROGeometryName = "DetectorROGeometry";
RO = new HadrontherapyDetectorROGeometry(ROGeometryName);
G4cout << "Going to register Parallel world...";
RegisterParallelWorld(RO);
G4cout << "... done" << G4endl;
//********************************************************************
}
/////////////////////////////////////////////////////////////////////////////
TrentoPassiveProtonBeamLine::~TrentoPassiveProtonBeamLine()
{
delete TrentoPassiveMessenger;
delete hadrontherapyDetectorConstruction;
}
using namespace std;
/////////////////////////////////////////////////////////////////////////////
G4VPhysicalVolume* TrentoPassiveProtonBeamLine::Construct()
{
// Sets default geometry and materials
SetDefaultDimensions();
// Construct the whole Passive Beam Line
ConstructTrentoPassiveProtonBeamLine();
//***************************** PW ***************************************
if (!hadrontherapyDetectorConstruction)
// HadrontherapyDetectorConstruction builds ONLY the phantom and the detector with its associated ROGeometry
hadrontherapyDetectorConstruction = new HadrontherapyDetectorConstruction(physicalTreatmentRoom);
//********************************************************************
hadrontherapyDetectorConstruction->InitializeDetectorROGeometry(RO,hadrontherapyDetectorConstruction->GetDetectorToWorldPosition());
return physicalTreatmentRoom;
}
// In the following method the DEFAULTS used in the geometry of
// passive beam line are provided
// HERE THE USER CAN CHANGE THE GEOMETRY CHARACTERISTICS OF BEAM
// LINE ELEMENTS, ALTERNATIVELY HE/SHE CAN USE THE MACRO FILE (IF A
// MESSENGER IS PROVIDED)
//
// DEFAULT MATERIAL ARE ALSO PROVIDED
// and COLOURS ARE ALSO DEFINED
// ----------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::SetDefaultDimensions()
{
// Set of coulors that can be used
white = new G4VisAttributes( G4Colour());
white -> SetVisibility(true);
white -> SetForceSolid(true);
blue = new G4VisAttributes(G4Colour(0. ,0. ,1.));
blue -> SetVisibility(true);
blue -> SetForceSolid(true);
gray = new G4VisAttributes( G4Colour(0.5, 0.5, 0.5 ));
gray-> SetVisibility(true);
gray-> SetForceSolid(true);
red = new G4VisAttributes(G4Colour(1. ,0. ,0.));
red-> SetVisibility(true);
red-> SetForceSolid(true);
yellow = new G4VisAttributes(G4Colour(1., 1., 0. ));
yellow-> SetVisibility(true);
yellow-> SetForceSolid(true);
green = new G4VisAttributes( G4Colour(25/255. , 255/255. , 25/255. ));
green -> SetVisibility(true);
green -> SetForceSolid(true);
darkGreen = new G4VisAttributes( G4Colour(0/255. , 100/255. , 0/255. ));
darkGreen -> SetVisibility(true);
darkGreen -> SetForceSolid(true);
darkOrange3 = new G4VisAttributes( G4Colour(205/255. , 102/255. , 000/255. ));
darkOrange3 -> SetVisibility(true);
darkOrange3 -> SetForceSolid(false);
skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
skyBlue -> SetVisibility(true);
skyBlue -> SetForceSolid(true);
// SCATTERING FOIL: it is a thin foil that provides the
// final diffusion of the beam.
G4double defaultScatteringFoilXSize = 0.75*cm;
ScatteringFoilXSize = defaultScatteringFoilXSize;
G4double defaultScatteringFoilYSize = 100*mm;
ScatteringFoilYSize = defaultScatteringFoilYSize;
G4double defaultScatteringFoilZSize = 100 *mm;
ScatteringFoilZSize = defaultScatteringFoilZSize;
G4double defaultScatteringFoilXPosition = -273.*cm;
ScatteringFoilXPosition = defaultScatteringFoilXPosition;
G4double defaultScatteringFoilYPosition = 0 *mm;
ScatteringFoilYPosition = defaultScatteringFoilYPosition;
G4double defaultScatteringFoilZPosition = 0 *mm;
ScatteringFoilZPosition = defaultScatteringFoilZPosition;
//PRE COLLIMATOR: it is a PMMA collimator
G4double defaultPreCollimatorXHalfSide = 12.5 * cm;
preCollimatorXHalfSide = defaultPreCollimatorXHalfSide;
G4double defaultPreCollimatorXPosition = -50.*cm;
preCollimatorXPosition = defaultPreCollimatorXPosition;
//DEFAULT DEFINITION OF THE AIR TUBE
G4double defaultYHalfSideAirTube= 5.*cm;
YHalfSideAirTube = defaultYHalfSideAirTube;
G4double defaultZHalfSideAirTube = 5.*cm;
ZHalfSideAirTube = defaultZHalfSideAirTube;
// DEFAULT DEFINITION OF THE MATERIALS
// All elements and compound definition follows the NIST database
// ELEMENTS
G4bool isotopes = false;
G4Material* aluminumNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Al", isotopes);
G4Material* copperNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu", isotopes);
G4Element* zincNist = G4NistManager::Instance()->FindOrBuildElement("Zn");
G4Element* copper = G4NistManager::Instance()->FindOrBuildElement("Cu");
G4Element* silicNist = G4NistManager::Instance()->FindOrBuildElement("Si");
G4Element* hydrogenNist = G4NistManager::Instance()->FindOrBuildElement("H");
G4Element* oxygenNist = G4NistManager::Instance()->FindOrBuildElement("O");
G4Element* carbonNist = G4NistManager::Instance()->FindOrBuildElement("C");
// COMPOUND
G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes);
G4Material* PMMANist = G4NistManager::Instance()->FindOrBuildMaterial("G4_PLEXIGLASS", isotopes);
G4Material* MylarNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_MYLAR");
G4int nComponents; // Number of components
G4int nAtoms; //Number of atoms
G4double fractionmass; // Fraction in mass of an element in a material
//Quartz
G4Material* SiO2 = new G4Material("quartz", 2.200*g/cm3, nComponents=2);
SiO2->AddElement(silicNist, nAtoms=1);
SiO2->AddElement(oxygenNist , nAtoms=2);
//Epoxy (for FR4 )
G4Material* Epoxy = new G4Material("Epoxy" , 1.2*g/cm3, nComponents=2);
Epoxy->AddElement(hydrogenNist, nAtoms=2);
Epoxy->AddElement(carbonNist, nAtoms=2);
//FR4 (Glass + Epoxy)
G4Material* FR4 = new G4Material("FR4" , 1.86*g/cm3, nComponents=2);
FR4->AddMaterial(SiO2, fractionmass=0.528);
FR4->AddMaterial(Epoxy, fractionmass=0.472);
//Brass
G4Material* brass = new G4Material("Brass", 8.40*g/cm3, nComponents=2);
brass -> AddElement(zincNist, fractionmass = 30 *perCent);
brass -> AddElement(copper, fractionmass = 70 *perCent);
//Plastic
G4Material* plastic = new G4Material("Plastic", 1.40*g/cm3, nComponents=3);
plastic -> AddElement(carbonNist, nAtoms = 21);
plastic -> AddElement(oxygenNist, nAtoms = 4);
plastic -> AddElement(hydrogenNist, nAtoms = 24);
//***************************** PW ***************************************
// DetectorROGeometry Material
new G4Material("dummyMat", 1., 1.*g/mole, 1.*g/cm3);
// MATERIAL ASSIGNMENT
// Support of the beam line
beamLineSupportMaterial = aluminumNist;
// Matreial of the monitor chamber
layerMonitorChamberMaterial = MylarNist;
layerDefaultMaterial = airNist;
internalStructureMaterial = FR4;
FoilMaterial = copperNist;
airgapMaterial = airNist;
// Material of the scattering foil
ScatteringFoilMaterial = copperNist;
//Material of the ridge filter
singleTrapMaterial = plastic;
// Materials of the collimators
preCollimatorMaterial = PMMANist;
CollimatorMaterial = brass;
// Material of the final brass tube
airTubeMaterial = airTube2Material = airTube3Material = airNist;
}
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::ConstructTrentoPassiveProtonBeamLine()
{
// -----------------------------
// Treatment room - World volume
//------------------------------
// Treatment room sizes
const G4double worldX = 400.0 *cm;
const G4double worldY = 400.0 *cm;
const G4double worldZ = 400.0 *cm;
G4bool isotopes = false;
G4Material* airNist = G4NistManager::Instance()->FindOrBuildMaterial("G4_AIR", isotopes);
G4Box* treatmentRoom = new G4Box("TreatmentRoom",
worldX,
worldY,
worldZ);
logicTreatmentRoom = new G4LogicalVolume(treatmentRoom,
airNist,
"logicTreatmentRoom",
0,0,0);
physicalTreatmentRoom = new G4PVPlacement(0,
G4ThreeVector(),
"physicalTreatmentRoom",
logicTreatmentRoom,
0,
false,
0);
// The treatment room is invisible in the Visualisation
logicTreatmentRoom -> SetVisAttributes (G4VisAttributes::Invisible);
// Components of the Passive Proton Beam Line
HadrontherapyBeamLineSupport();
HadrontherapyBeamMonitoring();
HadrontherapyBeamScatteringFoils();
HadrontherapyRidgeFilter();
HadrontherapyBeamCollimators();
}
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::HadrontherapyBeamLineSupport()
{
// ------------------//
// BEAM LINE SUPPORT //
//-------------------//
const G4double beamLineSupportXSize = 1.2*m;
const G4double beamLineSupportYSize = 20.*mm;
const G4double beamLineSupportZSize = 600.*mm;
const G4double beamLineSupportXPosition = -1745.09 *mm;
const G4double beamLineSupportYPosition = -230. *mm;
const G4double beamLineSupportZPosition = 0.*mm;
G4Box* beamLineSupport = new G4Box("BeamLineSupport",
beamLineSupportXSize,
beamLineSupportYSize,
beamLineSupportZSize);
G4LogicalVolume* logicBeamLineSupport = new G4LogicalVolume(beamLineSupport,
beamLineSupportMaterial,
"BeamLineSupport");
physiBeamLineSupport = new G4PVPlacement(0, G4ThreeVector(beamLineSupportXPosition,
beamLineSupportYPosition,
beamLineSupportZPosition),
"BeamLineSupport",
logicBeamLineSupport,
physicalTreatmentRoom,
false,
0);
// Visualisation attributes of the beam line support
logicBeamLineSupport -> SetVisAttributes(gray);
//---------------------------------//
// Beam line cover 1 (left panel) //
//---------------------------------//
const G4double beamLineCoverXSize = 1.2*m;
const G4double beamLineCoverYSize = 750.*mm;
const G4double beamLineCoverZSize = 10.*mm;
const G4double beamLineCoverXPosition = -1745.09 *mm;
const G4double beamLineCoverYPosition = -1000.*mm;
const G4double beamLineCoverZPosition = 600.*mm;
G4Box* beamLineCover = new G4Box("BeamLineCover",
beamLineCoverXSize,
beamLineCoverYSize,
beamLineCoverZSize);
G4LogicalVolume* logicBeamLineCover = new G4LogicalVolume(beamLineCover,
beamLineSupportMaterial,
"BeamLineCover");
physiBeamLineCover = new G4PVPlacement(0, G4ThreeVector(beamLineCoverXPosition,
beamLineCoverYPosition,
beamLineCoverZPosition),
"BeamLineCover",
logicBeamLineCover,
physicalTreatmentRoom,
false,
0);
// ---------------------------------//
// Beam line cover 2 (rigth panel) //
// ---------------------------------//
// It has the same characteristic of beam line cover 1 but set in a different position
physiBeamLineCover2 = new G4PVPlacement(0, G4ThreeVector(beamLineCoverXPosition,
beamLineCoverYPosition,
- beamLineCoverZPosition),
"BeamLineCover2",
logicBeamLineCover,
physicalTreatmentRoom,
false,
0);
logicBeamLineCover -> SetVisAttributes(blue);
}
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::HadrontherapyBeamMonitoring()
{
// ----------------------------
// MONITOR CHAMBER
// ----------------------------
// The monitor chamber is a ionisation chamber
// Each chamber consist in a sequence of 2 mm of air and
// 8 microm copper layers which contain 800 microm of Fr4 in a box
// that has the two layer of Mylar
////////////////////////////////////////////
///External Structure of the Monitor Chamber
////////////////////////////////////////////
const G4double monitorXSize = 12.*um;
const G4double monitorYSize = 12.7*cm;
const G4double monitorZSize = 12.7*cm;
const G4double shift = 17.*cm;
const G4double monitorlayer1XPosition = -269.*cm +shift;
const G4double monitorlayer2XPosition = -270.4104*cm +shift;
// First Mylar layer of the monitor chamber
G4Box* solidMonitorLayer1 = new G4Box("MonitorLayer1",
monitorXSize/2,
monitorYSize/2,
monitorZSize/2);
G4LogicalVolume* logicMonitorLayer1 = new G4LogicalVolume(solidMonitorLayer1,
layerMonitorChamberMaterial,
"MonitorLayer1");
physiMonitorLayer1 = new G4PVPlacement(0,
G4ThreeVector(monitorlayer1XPosition, 0.*cm, 0.*cm),
"MonitorLayer1",
logicMonitorLayer1,
physicalTreatmentRoom,
false,
0);
// Second Mylar layer of the monitor chamber
G4Box* solidMonitorLayer2 = new G4Box("MonitorLayer2",
monitorXSize/2,
monitorYSize/2,
monitorZSize/2);
G4LogicalVolume* logicMonitorLayer2 = new G4LogicalVolume(solidMonitorLayer2,
layerMonitorChamberMaterial,
"MonitorLayer2");
physiMonitorLayer2 = new G4PVPlacement(0,
G4ThreeVector(monitorlayer2XPosition, 0.*cm, 0.*cm),
"MonitorLayer2",
logicMonitorLayer2,
physicalTreatmentRoom,
false,
0);
logicMonitorLayer1 -> SetVisAttributes(gray);
logicMonitorLayer2 -> SetVisAttributes(gray);
///////////////////////////////////////////
// Internal Structure of the Monitor Chamber
////////////////////////////////////////////
const G4double layerThickness = 816*um;
const G4double layerXposition = -270.2684*cm;
const G4int nofLayers = 5;
const G4double internalStructureThickness = 800.*um;
const G4double airGapThickness = 2.*mm;
const G4double foilThickness = 8.*um;
const G4double FirstCoppperLayerXPosition = -404.*um;
const G4double SecondCoppperLayerXPosition = 404.*um;
const G4double InternalStructureXPosition = 0.;
// Air Layer
G4VSolid* SolidAirLayer= new G4Box("Layer",
layerThickness,
monitorYSize/2,
monitorZSize/2);
new G4LogicalVolume(SolidAirLayer,
layerDefaultMaterial,
"Layer");
// First Copper Layer
G4VSolid* SolidFirstCoppperLayer = new G4Box("SolidFirstCoppperLayer",
foilThickness/2,
monitorYSize/2,
monitorZSize/2);
G4LogicalVolume* LogicFirstCoppperLayer = new G4LogicalVolume(
SolidFirstCoppperLayer,
FoilMaterial,
"SolidFirstCoppperLayer");
// Fr4 Internal Layer
G4VSolid* SolidInternalStructure = new G4Box("SolidInternalStructure",
internalStructureThickness/2,
monitorYSize/2,
monitorZSize/2);
G4LogicalVolume* LogicInternalStructure = new G4LogicalVolume(
SolidInternalStructure,
internalStructureMaterial,
"SolidInternalStructure");
// Second Copper Layer
G4VSolid* SolidSecondCoppperLayer = new G4Box("SolidSecondCoppperLayer",
foilThickness/2,
monitorYSize/2,
monitorZSize/2); // its size
G4LogicalVolume* LogicSecondCoppperLayer= new G4LogicalVolume(
SolidSecondCoppperLayer,
FoilMaterial,
"SolidSecondCoppperLayer");
G4RotationMatrix Ra, Rm;
G4ThreeVector Ta;
G4Transform3D Tr;
G4AssemblyVolume* assemblyMonitor = new G4AssemblyVolume();
Ta.setX(FirstCoppperLayerXPosition); Ta.setY(0.); Ta.setZ(0.);
Tr = G4Transform3D(Ra,Ta);
assemblyMonitor->AddPlacedVolume(LogicFirstCoppperLayer, Tr);
Ta.setX(InternalStructureXPosition); Ta.setY(0.); Ta.setZ(0.);
Tr = G4Transform3D(Ra,Ta);
assemblyMonitor->AddPlacedVolume(LogicInternalStructure, Tr );
Ta.setX(SecondCoppperLayerXPosition); Ta.setY(0.); Ta.setZ(0.);
Tr = G4Transform3D(Ra,Ta);
assemblyMonitor->AddPlacedVolume(LogicSecondCoppperLayer, Tr );
for( unsigned int i = 0; i<nofLayers; i++ )
{
G4ThreeVector Tm(shift+layerXposition + i*(airGapThickness), 0., 0.);
Tr = G4Transform3D(Rm,Tm);
assemblyMonitor -> MakeImprint(logicTreatmentRoom, Tr);
}
}
void TrentoPassiveProtonBeamLine::HadrontherapyBeamScatteringFoils()
{
// ---------------------------//
// SCATTERING FOIL //
// ---------------------------//
// It is a metal foil and provides the
// initial diffusion of the beam.
ScatteringFoil = new G4Box("ScatteringFoil",
ScatteringFoilXSize,
ScatteringFoilYSize,
ScatteringFoilZSize);
logicScatteringFoil = new G4LogicalVolume(ScatteringFoil,
ScatteringFoilMaterial,
"ScatteringFoil");
physiScatteringFoil = new G4PVPlacement(0, G4ThreeVector(ScatteringFoilXPosition,
ScatteringFoilYPosition,
ScatteringFoilZPosition),
"SeconScatteringFoil",
logicScatteringFoil,
physicalTreatmentRoom,
false,
0);
logicScatteringFoil -> SetVisAttributes(skyBlue);
}
void TrentoPassiveProtonBeamLine::HadrontherapyRidgeFilter()
{
// ---------------------------- //
// THE Ridge Filter //
// -----------------------------//
// Energy degreader of
// primary beam. Made of a series of pin-substructures.
G4double ridgeXPosition = -200*cm;
const G4double XBase = 0.1 *mm;
const G4double YBase = 38.75*mm;
G4VSolid* RidgeBase = new G4Box("Base_RidgeFilter",
XBase,
YBase,
YBase);
G4LogicalVolume* RidgeBaseLog = new G4LogicalVolume(RidgeBase,
singleTrapMaterial,
"Base_RidgeFilter");
new G4PVPlacement(0,
G4ThreeVector(
-199.7*cm,
0.,
0.),
"Base_RidgeFilter",
RidgeBaseLog,
physicalTreatmentRoom,
false,
0);
RidgeBaseLog->SetVisAttributes(yellow);
G4double x0 = 1.215*mm;
G4double x1 = 1*mm;
G4double x2 = 0.95*mm;
G4double x3 = 0.87*mm;
G4double x4 = 0.76*mm;
G4double x5 = 0.71*mm;
G4double x6 = 0.65*mm;
G4double x7 = 0.56*mm;
G4double x8 = 0.529*mm;
G4double x9 = 0.258*mm;
G4double x10 = 0.225*mm;
G4double x11 = 0.144*mm;
G4double x12 = 0.055*mm;
G4double heigth = 0.13*mm;
G4double heigth0 = 0.11*mm;
G4double heigth1 = 2.3*mm;
G4double heigth2 = 0.65*mm;
G4double heigth3 = 1.9*mm;
G4double heigth4 = 0.615*mm;
G4double heigth5 = 2.23*mm;
G4double heigth6 = 0.3*mm;
G4double heigth7 = 4.1*mm;
G4double heigth8 = 0.1*mm;
G4double heigth9 = 0.105*mm;
G4double heigth10 = 0.065*mm;
G4VSolid* Trap00 = new G4Trd("singleTrap00", x0, x1, x0, x1, heigth);
G4VSolid* Trap0 = new G4Trd("singleTrap0", x1, x2, x1, x2, heigth0);
G4VSolid* Trap1 = new G4Trd("singleTrap1", x2, x3, x2, x3, heigth1);
G4VSolid* Trap2 = new G4Trd("singleTrap2", x3, x4, x3, x4, heigth2);
G4VSolid* Trap3 = new G4Trd("singleTrap3", x4, x5, x4, x5, heigth3);
G4VSolid* Trap4 = new G4Trd("singleTrap4", x5, x6, x5, x6, heigth4);
G4VSolid* Trap5 = new G4Trd("singleTrap5", x6, x7, x6, x7, heigth5);
G4VSolid* Trap6 = new G4Trd("singleTrap6", x7, x8, x7, x8, heigth6);
G4VSolid* Trap7 = new G4Trd("singleTrap7", x8, x9, x8, x9, heigth7);
G4VSolid* Trap8 = new G4Trd("singleTrap8", x9, x10, x9, x10, heigth8);
G4VSolid* Trap9 = new G4Trd("singleTrap9", x10, x11, x10, x11, heigth9);
G4VSolid* Trap10 = new G4Trd("singleTrap10", x11, x12, x11, x12, heigth10);
G4ThreeVector tr0(0., 0., 0.24);
G4ThreeVector tr1(0., 0., 2.54);
G4ThreeVector tr2(0., 0., 2.55);
G4ThreeVector tr3(0., 0., 2.845);
G4ThreeVector tr4(0., 0., 4.4);
G4RotationMatrix* yRot = new G4RotationMatrix;
yRot->rotateY(0);
G4UnionSolid* unionTrap00 = new G4UnionSolid("Trap01", Trap00, Trap0, yRot, tr0);
G4UnionSolid* unionTrap01 = new G4UnionSolid("Trap01", unionTrap00, Trap1, yRot, tr1);
G4UnionSolid* unionTrap23 = new G4UnionSolid("Trap23", Trap2, Trap3, yRot, tr2);
G4UnionSolid* unionTrap45 = new G4UnionSolid("Trap45", Trap4, Trap5, yRot, tr3);
G4UnionSolid* unionTrap67 = new G4UnionSolid("Trap67", Trap6, Trap7, yRot, tr4);
G4ThreeVector tr03(0., 0., 5.09);
G4UnionSolid* unionTrap03 = new G4UnionSolid("unionTrap03", unionTrap01, unionTrap23, yRot, tr03);
G4ThreeVector tr05(0., 0., 7.935);
G4UnionSolid* unionTrap05 = new G4UnionSolid("unionTrap05", unionTrap03, unionTrap45, yRot, tr05);
G4ThreeVector tr_blocco1(0., 0., 12.335);
G4UnionSolid* unionTrap_blocco1 = new G4UnionSolid("unionTrap_blocco1", unionTrap05, unionTrap67, yRot, tr_blocco1);
G4ThreeVector tr_blocco2( 0., 0., 12.435);
G4UnionSolid* unionTrap_blocco2 = new G4UnionSolid("unionTrap_blocco2", unionTrap_blocco1, Trap8, yRot, tr_blocco2);
G4ThreeVector tr_blocco3(0., 0., 12.54);
G4UnionSolid* unionTrap_blocco3 = new G4UnionSolid("unionTrap_blocco3", unionTrap_blocco2, Trap9, yRot, tr_blocco3);
G4ThreeVector tr_tot( 0., 0., 12.605);
G4UnionSolid* unionTrap = new G4UnionSolid("unionTrap", unionTrap_blocco3, Trap10, yRot, tr_tot);
G4LogicalVolume* singleTrapLog = new G4LogicalVolume(unionTrap, singleTrapMaterial, "singleTrap");
singleTrapLog->SetVisAttributes(yellow);
G4int numberOfLayers = 31;
G4double minZ = -37.5*mm;
G4double minY = -37.5*mm;
G4double sum_space = 1.25*mm;
vector<G4ThreeVector> singleTrapPositions;
for (int i = 0; i < numberOfLayers; i++)
{
for (int j = 0; j < numberOfLayers; j++)
{
singleTrapPositions.push_back({-0.01*cm+ridgeXPosition,
minY + 2*i*sum_space,
minZ + 2*j*sum_space,});
}
}
G4double ti = - 90. *deg;
G4RotationMatrix rt;
rt.rotateY(ti);
G4int peaks = numberOfLayers*numberOfLayers;
for (int i = 0; i < peaks; i++)
{
ostringstream tName;tName << "singleTrap" << i;
new G4PVPlacement(G4Transform3D(rt,
singleTrapPositions[i]),
singleTrapLog,
"tName.str()",
logicTreatmentRoom,
0,
i);
}
}
void TrentoPassiveProtonBeamLine::HadrontherapyBeamCollimators()
{
// ------------------------//
// PRE - COLLIMATOR //
// -----------------------//
// It is a plastic collimator to limit neutron dose and reduce activation
const G4double preCollimatorYHalfSide = 10.*cm;
const G4double preCollimatorZHalfSide = 10.*cm;
preCollimator = new G4Box("PreCollimator",
preCollimatorXHalfSide,
preCollimatorYHalfSide,
preCollimatorZHalfSide);
G4LogicalVolume* logicPreCollimator = new G4LogicalVolume(preCollimator,
preCollimatorMaterial,
"PreCollimator");
physiPreCollimator = new G4PVPlacement(0,
G4ThreeVector(
-50.*cm,
0.,
0.),
"PreCollimator",
logicPreCollimator,
physicalTreatmentRoom,
false,
0);
logicPreCollimator -> SetVisAttributes(white);
// -----------------//
// COLLIMATOR //
// -----------------//
// It is a brass collimator
G4double collimatorYHalfSide = 10.*cm;
G4double collimatorZHalfSide = 10.*cm;
G4double collimatorXHalfSide = 3.25*cm;
G4double CollimatorXPosition = -34.25*cm;
Collimator = new G4Box("Collimator",
collimatorXHalfSide,
collimatorYHalfSide,
collimatorZHalfSide);
G4LogicalVolume* logicCollimator = new G4LogicalVolume(Collimator,
CollimatorMaterial,
"Collimator");
physiCollimator = new G4PVPlacement(0, G4ThreeVector(CollimatorXPosition,
0.,
0.),
"Collimator",
logicCollimator,
physicalTreatmentRoom,
false,
0);
logicCollimator -> SetVisAttributes(darkGreen);
// ---------------------------------//
// AIR BOX Collimator //
// ---------------------------------//
solidAirTube = new G4Box("AirTube",
collimatorXHalfSide,
YHalfSideAirTube,
ZHalfSideAirTube);
G4LogicalVolume* logicAirTube = new G4LogicalVolume(solidAirTube,
airTubeMaterial,
"AirTube",
0, 0, 0);
physiAirTube = new G4PVPlacement(0, G4ThreeVector(0,
0.,
0.),
"AirTube",
logicAirTube,
physiCollimator,
false,
0);
logicAirTube -> SetVisAttributes(darkOrange3);
// // ---------------------------------//
// // AIR BOX PreCollimator //
// // ---------------------------------//
solidAirPreTube = new G4Box("AirPreTube",
preCollimatorXHalfSide,
YHalfSideAirTube,
ZHalfSideAirTube);
G4LogicalVolume* logicAirPreTube = new G4LogicalVolume(solidAirPreTube,
airTubeMaterial,
"AirPreTube",
0, 0, 0);
physiAirPreTube = new G4PVPlacement(0,
G4ThreeVector(0,
0.,
0.),
"AirPreTube",
logicAirPreTube,
physiPreCollimator,
false,
0);
logicAirPreTube -> SetVisAttributes(darkOrange3);
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////// MESSENGER ///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::SetScatteringFoilXSize(G4double value)
{
ScatteringFoil -> SetXHalfLength(value);
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
G4cout <<"The X size of the second scattering foil is (mm):"<<
((ScatteringFoil -> GetXHalfLength())*2.)/mm
<< G4endl;
}
void TrentoPassiveProtonBeamLine::SetPreCollimatorXSize(G4double value)
{
preCollimator -> SetXHalfLength(value);
G4cout<<"The size of the pre collimator is (mm)"
<< ((preCollimator -> GetXHalfLength())*2)/mm << G4endl;
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
}
void TrentoPassiveProtonBeamLine::SetPreCollimatorXPosition(G4double value)
{
physiPreCollimator -> SetTranslation(G4ThreeVector(value, 0., 0.));
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
G4cout <<" The pre collimator is translated to" << value/mm <<"mm along the X axis" << G4endl;
}
void TrentoPassiveProtonBeamLine::SetAirTubeYSize(G4double value)
{
solidAirTube -> SetYHalfLength(value);
G4cout<<"The y side of brass tube is (mm)"
<< ((preCollimator -> GetYHalfLength())*2) << G4endl;
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
}
void TrentoPassiveProtonBeamLine::SetAirTubeZSize(G4double value)
{
solidAirTube -> SetZHalfLength(value);
G4cout<<"The z side of the brass tube is (mm)"
<< ((Collimator -> GetZHalfLength())*2) << G4endl;
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
}
/////////////////////////////////////////////////////////////////////////////
void TrentoPassiveProtonBeamLine::SetScattererMaterial(G4String materialChoice)
{
if (G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice, false) )
{
if (pttoMaterial)
{
ScatteringFoilMaterial = pttoMaterial;
logicScatteringFoil -> SetMaterial(pttoMaterial);
G4cout << "The material of the Scatterer has been changed to " << materialChoice << G4endl;
}
}
else
{
G4cout << "WARNING: material \"" << materialChoice << "\" doesn't exist in NIST elements/materials"
" table [located in $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
G4cout << "Use command \"/parameter/nist\" to see full materials list!" << G4endl;
}
}
@@ -0,0 +1,138 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Hadrontherapy advanced example for Geant4
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy
#include "TrentoPassiveProtonBeamLine.hh"
#include "TrentoPassiveProtonBeamLineMessenger.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4SystemOfUnits.hh"
TrentoPassiveProtonBeamLineMessenger::TrentoPassiveProtonBeamLineMessenger(TrentoPassiveProtonBeamLine* TrentoLine)
:TrentoPassiveProton(TrentoLine)
{
changeTheBeamLineDir = new G4UIdirectory("/ChangeBeamLine/");
changeTheBeamLineDir -> SetGuidance("Command to change the transport beam line");
changeTheBeamLineNameCmd = new G4UIcmdWithAString("/ChangeBeamLine/beamLineName",this);
changeTheBeamLineNameCmd -> SetGuidance("Insert the name of the beam line you want simulate");
changeTheBeamLineNameCmd -> SetParameterName("List",false);
changeTheBeamLineNameCmd -> AvailableForStates(G4State_PreInit);
modulatorDir = new G4UIdirectory("/modulator/");
modulatorDir -> SetGuidance("Command to rotate the modulator wheel");
beamLineDir = new G4UIdirectory("/beamLine/");
beamLineDir -> SetGuidance("set specification of range shifter");
ScatteringFoilXSizeCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/ScatteringFoil/thickness",this);
ScatteringFoilXSizeCmd -> SetGuidance("Set half thickness of scattering foil");
ScatteringFoilXSizeCmd -> SetParameterName("Size",false);
ScatteringFoilXSizeCmd -> SetDefaultUnit("mm");
ScatteringFoilXSizeCmd -> SetUnitCandidates("mm cm m");
ScatteringFoilXSizeCmd -> AvailableForStates(G4State_Idle);
scatteringFoilMatCmd = new G4UIcmdWithAString("/beamLine/ScatteringFoil/material",this);
scatteringFoilMatCmd -> SetGuidance("Set material of scatterer");
scatteringFoilMatCmd -> SetParameterName("choice",false);
scatteringFoilMatCmd -> AvailableForStates(G4State_Idle);
preCollimatorXSizeCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/preCollimator/XSize",this);
preCollimatorXSizeCmd -> SetGuidance("Set half x side of pre collimator");
preCollimatorXSizeCmd -> SetParameterName("Size",false);
preCollimatorXSizeCmd -> SetDefaultUnit("mm");
preCollimatorXSizeCmd -> SetUnitCandidates("mm cm m");
preCollimatorXSizeCmd -> AvailableForStates(G4State_Idle);
preCollimatorXPositionCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/preCollimator/XPosition",this);
preCollimatorXPositionCmd -> SetGuidance("Set the position along x ");
preCollimatorXPositionCmd -> SetParameterName("Position",false);
preCollimatorXPositionCmd -> SetDefaultUnit("mm");
preCollimatorXPositionCmd -> SetUnitCandidates("mm cm m");
preCollimatorXPositionCmd -> AvailableForStates(G4State_Idle);
AirTubeYSizeCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/airTube/YSide",this);
AirTubeYSizeCmd -> SetGuidance("Set of pre collimator the outer radius of the hole in the collimator ");
AirTubeYSizeCmd -> SetParameterName("Radius",false);
AirTubeYSizeCmd -> SetDefaultUnit("mm");
AirTubeYSizeCmd -> SetUnitCandidates("mm cm m");
AirTubeYSizeCmd -> AvailableForStates(G4State_Idle);
AirTubeZSizeCmd = new G4UIcmdWithADoubleAndUnit("/beamLine/FirstCollimator/innerRadius",this);
AirTubeZSizeCmd -> SetGuidance("Set the inner radius of the collimator ");
AirTubeZSizeCmd -> SetParameterName("Radius",false);
AirTubeZSizeCmd -> SetDefaultUnit("mm");
AirTubeZSizeCmd -> SetUnitCandidates("mm cm m");
AirTubeZSizeCmd -> AvailableForStates(G4State_Idle);
}
TrentoPassiveProtonBeamLineMessenger::~TrentoPassiveProtonBeamLineMessenger()
{
delete AirTubeZSizeCmd;
delete AirTubeYSizeCmd;
delete ScatteringFoilXSizeCmd;
delete scatteringFoilMatCmd;
delete preCollimatorXSizeCmd;
delete beamLineDir;
delete modulatorDir;
}
void TrentoPassiveProtonBeamLineMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
{
if( command == ScatteringFoilXSizeCmd )
{TrentoPassiveProton -> SetScatteringFoilXSize
(ScatteringFoilXSizeCmd -> GetNewDoubleValue(newValue));}
else if( command == scatteringFoilMatCmd )
{ TrentoPassiveProton -> SetScattererMaterial(newValue);}
else if( command == preCollimatorXSizeCmd )
{ TrentoPassiveProton -> SetPreCollimatorXSize
(preCollimatorXSizeCmd -> GetNewDoubleValue(newValue));}
else if( command == preCollimatorXPositionCmd )
{ TrentoPassiveProton -> SetPreCollimatorXPosition
(preCollimatorXPositionCmd -> GetNewDoubleValue(newValue));}
else if( command == AirTubeYSizeCmd )
{ TrentoPassiveProton -> SetAirTubeYSize
(AirTubeYSizeCmd -> GetNewDoubleValue(newValue));}
else if( command == AirTubeZSizeCmd )
{ TrentoPassiveProton -> SetAirTubeZSize
(AirTubeZSizeCmd -> GetNewDoubleValue(newValue));}
}