Import Geant4 10.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2018-12-07 15:15:39 +01:00
parent 6aa23be517
commit db49709b53
11370 changed files with 187480 additions and 160142 deletions
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -45,7 +45,7 @@
#include "G4UIcmdWithAString.hh"
Collimator40BeamLineMessenger::Collimator40BeamLineMessenger(Collimator40BeamLine* beamLine)
Collimator40BeamLineMessenger::Collimator40BeamLineMessenger(Collimator40BeamLine* beamLine)
:collimator40(beamLine)
{
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -44,12 +44,9 @@
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
Collimator50BeamLineMessenger::Collimator50BeamLineMessenger(Collimator50BeamLine* beamLine)
Collimator50BeamLineMessenger::Collimator50BeamLineMessenger(Collimator50BeamLine* beamLine)
:collimator50(beamLine)
{
beamLineDir = new G4UIdirectory("/beamLine/");
beamLineDir -> SetGuidance("set specification of range shifter");
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -1,114 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c),
// G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTAnalysisFileMessenger.hh"
#include "IORTAnalysisManager.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithABool.hh"
#include "G4UIdirectory.hh"
#include "IORTMatrix.hh"
/////////////////////////////////////////////////////////////////////////////
IORTAnalysisFileMessenger::IORTAnalysisFileMessenger(IORTAnalysisManager* amgr) :
AnalysisManager(amgr)
{
secondaryCmd = new G4UIcmdWithABool("/analysis/secondary",this);
secondaryCmd -> SetParameterName("secondary", true);
secondaryCmd -> SetDefaultValue("true");
secondaryCmd -> SetGuidance("Set if dose/fluence for the secondary particles will be written"
"\n[usage]: /analysis/secondary [true/false]");
secondaryCmd -> AvailableForStates(G4State_Idle, G4State_PreInit);
DoseMatrixCmd = new G4UIcmdWithAString("/analysis/writeDoseFile",this);
DoseMatrixCmd->SetGuidance("Write the dose/fluence to an ASCII file");
DoseMatrixCmd->SetDefaultValue("Dose.out");
DoseMatrixCmd->SetParameterName("choice",true);
// 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
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);
}
/////////////////////////////////////////////////////////////////////////////
IORTAnalysisFileMessenger::~IORTAnalysisFileMessenger()
{
delete secondaryCmd;
delete DoseMatrixCmd;
delete FileNameCmd;
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisFileMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
{
if (command == secondaryCmd)
{
if (IORTMatrix::GetInstance())
{
IORTMatrix::GetInstance() -> secondary = secondaryCmd -> GetNewBoolValue(newValue);
}
}
else if (command == DoseMatrixCmd) // Filename can be passed here TODO
{
if ( IORTMatrix * pMatrix = IORTMatrix::GetInstance() )
{
pMatrix -> TotalEnergyDeposit();
pMatrix -> StoreDoseFluenceAscii(newValue);
pMatrix -> StoreDoseFluenceRoot();
// Finalize & write output file
IORTAnalysisManager::GetInstance() -> flush();
}
}
else if (command == FileNameCmd)
{
AnalysisManager->SetAnalysisFileName(newValue);
IORTAnalysisManager::GetInstance() -> book(); // Book for a new output file
}
}
@@ -1,458 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c),
// G.A.P. Cirrone(d), F.Romano(d)
//
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTAnalysisManager.hh"
#include "IORTMatrix.hh"
#include "IORTAnalysisFileMessenger.hh"
#include <time.h>
IORTAnalysisManager* IORTAnalysisManager::instance = 0;
IORTAnalysisManager::IORTAnalysisManager() :
analysisFileName("DoseDistribution"),
eventCounter(0)
{
fMess = new IORTAnalysisFileMessenger(this);
}
/////////////////////////////////////////////////////////////////////////////
IORTAnalysisManager::~IORTAnalysisManager()
{
if (fMess)
delete fMess;
delete G4AnalysisManager::Instance();
}
/////////////////////////////////////////////////////////////////////////////
IORTAnalysisManager* IORTAnalysisManager::GetInstance()
{
if (instance == 0) instance = new IORTAnalysisManager;
return instance;
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SetAnalysisFileName(G4String aFileName)
{
analysisFileName = aFileName;
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::book()
{
// Create analysis manager
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->SetVerboseLevel(1);
man->SetFirstHistoId(1);
man->SetFirstNtupleId(1);
man->OpenFile(analysisFileName);
// Create the histograms with the energy deposit along the X axis
//ID=1 <different waterthicknesses are accoutned for in ROOT-analysis stage>
man->CreateH1("braggPeak","slice, energy", 400, 0., 80); //
//ID=2
man->CreateH1("h20","Secondary protons - slice, energy", 400, 0., 400.);
//ID=3
man->CreateH1("h30","Secondary neutrons - slice, energy", 400, 0., 400.);
//ID=4
man->CreateH1("h40","Secondary alpha - slice, energy", 400, 0., 400.);
//ID=5
man->CreateH1("h50","Secondary gamma - slice, energy", 400, 0., 400.);
//ID=6
man->CreateH1("h60","Secondary electron - slice, energy", 400, 0., 400.);
//ID=7
man->CreateH1("h70","Secondary triton - slice, energy", 400, 0., 400.);
//ID=8
man->CreateH1("h80","Secondary deuteron - slice, energy", 400, 0., 400.);
//ID=9
man->CreateH1("h90","Secondary pion - slice, energy", 400, 0., 400.);
//ID=10
man->CreateH1("h100","Energy distribution of secondary electrons", 70, 0., 70.);
//ID=11
man->CreateH1("h110","Energy distribution of secondary photons", 70, 0., 70.);
//ID=12
man->CreateH1("h120","Energy distribution of secondary deuterons", 70, 0., 70.);
//ID = 13
man->CreateH1("h130","Energy distribution of secondary tritons", 70, 0., 70.);
//ID = 14
man->CreateH1("h140","Energy distribution of secondary alpha particles", 70, 0., 70.);
//ID = 15
man->CreateH1("heliumEnergyAfterPhantom",
"Energy distribution of secondary helium fragments after the phantom",
70, 0., 500.);
//ID= 16
man->CreateH1("hydrogenEnergyAfterPhantom",
"Energy distribution of secondary helium fragments after the phantom",
70, 0., 500.);
//Now the ntuples
//ID = 1
man->CreateNtuple("kinFragNtuple",
"Kinetic energy by voxel & fragment");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleIColumn("A");
man->CreateNtupleDColumn("Z");
man->CreateNtupleDColumn("kineticEnergy");
man->FinishNtuple();
//ID = 2
man->CreateNtuple("kineticEnergyPrimaryNtuple",
"Kinetic energy by voxel of primary");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleDColumn("kineticEnergy");
man->FinishNtuple();
//ID = 3
man->CreateNtuple("doseFragNtuple",
"Energy deposit by voxel & fragment");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleIColumn("A");
man->CreateNtupleDColumn("Z");
man->CreateNtupleDColumn("energy");
man->FinishNtuple();
// ID =4
man->CreateNtuple("fluenceFragNtuple",
"Fluence by voxel & fragment");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleIColumn("A");
man->CreateNtupleDColumn("Z");
man->CreateNtupleDColumn("fluence");
man->FinishNtuple();
// ID=5
man->CreateNtuple("letFragNtuple",
"Let by voxel & fragment");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleIColumn("A");
man->CreateNtupleDColumn("Z");
man->CreateNtupleDColumn("letT");
man->CreateNtupleDColumn("letD");
man->FinishNtuple();
//ID=6
man->CreateNtuple("theROOTNtuple",
"Energy deposit by slice");
man->CreateNtupleIColumn("i");
man->CreateNtupleIColumn("j");
man->CreateNtupleIColumn("k");
man->CreateNtupleDColumn("energy");
man->FinishNtuple();
//ID=7
man->CreateNtuple("theROOTIonTuple",
"Generic ion information");
man->CreateNtupleIColumn("a");
man->CreateNtupleDColumn("z");
man->CreateNtupleIColumn("occupancy");
man->CreateNtupleDColumn("energy");
man->FinishNtuple();
//ID=8
man->CreateNtuple("fragmentNtuple",
"Fragments");
man->CreateNtupleIColumn("A");
man->CreateNtupleDColumn("Z");
man->CreateNtupleDColumn("energy");
man->CreateNtupleDColumn("posX");
man->CreateNtupleDColumn("posY");
man->CreateNtupleDColumn("posZ");
man->FinishNtuple();
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::FillEnergyDeposit(G4int i,
G4int j,
G4int k,
G4double energy)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(6,0,i);
man->FillNtupleIColumn(6,1,j);
man->FillNtupleIColumn(6,2,k);
man->FillNtupleDColumn(6,3,energy);
man->AddNtupleRow(6);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::BraggPeak(G4int slice, G4double energy)
{
//FIXME
G4AnalysisManager::Instance()->FillH1(1,slice,energy);
//histo1->SetBinContent(slice, energy); //This uses setbincontent instead of fill to get labels correct
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryProtonEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(2,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryNeutronEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(3,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryAlphaEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(4,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryGammaEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(5,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryElectronEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(6,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryTritonEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(7,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryDeuteronEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(8,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::SecondaryPionEnergyDeposit(G4int slice, G4double energy)
{
G4AnalysisManager::Instance()->FillH1(9,slice,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::electronEnergyDistribution(G4double energy)
{
G4AnalysisManager::Instance()->FillH1(10,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::gammaEnergyDistribution(G4double energy)
{
G4AnalysisManager::Instance()->FillH1(11,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::deuteronEnergyDistribution(G4double energy)
{
G4AnalysisManager::Instance()->FillH1(12,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::tritonEnergyDistribution(G4double energy)
{
G4AnalysisManager::Instance()->FillH1(13,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::alphaEnergyDistribution(G4double energy)
{
G4AnalysisManager::Instance()->FillH1(14,energy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::heliumEnergy(G4double secondaryParticleKineticEnergy)
{
G4AnalysisManager::Instance()->FillH1(15,secondaryParticleKineticEnergy);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::hydrogenEnergy(G4double secondaryParticleKineticEnergy)
{
G4AnalysisManager::Instance()->FillH1(16,secondaryParticleKineticEnergy);
}
/////////////////////////////////////////////////////////////////////////////
// FillKineticFragmentTuple create an ntuple where the voxel indexs, the atomic number and mass and the kinetic
// energy of all the particles interacting with the phantom, are stored
void IORTAnalysisManager::FillKineticFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z, G4double kinEnergy)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(1,0,i);
man->FillNtupleIColumn(1,1,j);
man->FillNtupleIColumn(1,2,k);
man->FillNtupleIColumn(1,3,A);
man->FillNtupleDColumn(1,4,Z);
man->FillNtupleDColumn(1,5,kinEnergy);
man->AddNtupleRow(1);
}
/////////////////////////////////////////////////////////////////////////////
// FillKineticEnergyPrimaryNTuple creates a ntuple where the voxel indexs and the kinetic
// energies of ONLY primary particles interacting with the phantom, are stored
void IORTAnalysisManager::FillKineticEnergyPrimaryNTuple(G4int i, G4int j, G4int k, G4double kinEnergy)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(2,0,i);
man->FillNtupleIColumn(2,1,j);
man->FillNtupleIColumn(2,2,k);
man->FillNtupleDColumn(2,3,kinEnergy);
man->AddNtupleRow(2);
}
/////////////////////////////////////////////////////////////////////////////
// This function is called only if ROOT is activated.
// It is called by the IORTMatric.cc class file and it is used to create two ntuples containing
// the total energy deposited and the fluence values, in each voxel and per any particle (primary
// and secondary particles beam)
void IORTAnalysisManager::FillVoxelFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z,
G4double energy, G4double fluence)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(3,0,i);
man->FillNtupleIColumn(3,1,j);
man->FillNtupleIColumn(3,2,k);
man->FillNtupleIColumn(3,3,A);
man->FillNtupleDColumn(3,4,Z);
man->FillNtupleDColumn(3,5,energy);
man->AddNtupleRow(3);
// Fill the ntuple containing the voxel, mass and atomic number and the fluence
if (i==1 && Z==1) {
man->FillNtupleIColumn(4,0,i);
man->FillNtupleIColumn(4,1,j);
man->FillNtupleIColumn(4,2,k);
man->FillNtupleIColumn(4,3,A);
man->FillNtupleDColumn(4,4,Z);
man->FillNtupleDColumn(4,5,fluence);
man->AddNtupleRow(4);
}
}
void IORTAnalysisManager::FillLetFragmentTuple(G4int i, G4int j, G4int k, G4int A, G4double Z,
G4double letT, G4double letD)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(5,0,i);
man->FillNtupleIColumn(5,1,j);
man->FillNtupleIColumn(5,2,k);
man->FillNtupleIColumn(5,3,A);
man->FillNtupleDColumn(5,4,Z);
man->FillNtupleDColumn(5,5,letT);
man->FillNtupleDColumn(5,6,letD);
man->AddNtupleRow(5);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::FillFragmentTuple(G4int A, G4double Z, G4double energy,
G4double posX, G4double posY, G4double posZ)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(8,0,A);
man->FillNtupleDColumn(8,1,Z);
man->FillNtupleDColumn(8,2,energy);
man->FillNtupleDColumn(8,3,posX);
man->FillNtupleDColumn(8,4,posY);
man->FillNtupleDColumn(8,5,posZ);
man->AddNtupleRow(8);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::genericIonInformation(G4int a,
G4double z,
G4int electronOccupancy,
G4double energy)
{
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->FillNtupleIColumn(7,0,a);
man->FillNtupleDColumn(7,1,z);
man->FillNtupleIColumn(7,2,electronOccupancy);
man->FillNtupleDColumn(7,3,energy);
man->AddNtupleRow(7);
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::startNewEvent()
{
eventCounter++;
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::setGeometryMetaData(G4double endDetectorPosition, G4double waterThickness,
G4double phantomCenter)
{
detectorDistance = endDetectorPosition;
phantomDepth = waterThickness;
phantomCenterDistance = phantomCenter;
}
/////////////////////////////////////////////////////////////////////////////
void IORTAnalysisManager::setBeamMetaData(G4double meanKineticEnergy,G4double sigmaEnergy)
{
beamEnergy = meanKineticEnergy;
energyError = sigmaEnergy;
}
/////////////////////////////////////////////////////////////////////////////
// Flush data & close the file
void IORTAnalysisManager::flush()
{
// Save histograms
G4AnalysisManager* man = G4AnalysisManager::Instance();
man->Write();
man->CloseFile();
eventCounter = 0;
}
@@ -33,14 +33,13 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include <cmath>
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4SystemOfUnits.hh"
#include "globals.hh"
#include "G4SDManager.hh"
#include "G4RunManager.hh"
@@ -60,17 +59,15 @@
#include "G4VisAttributes.hh"
#include "G4NistManager.hh"
#include "IORTDetectorConstruction.hh"
#include "IORTDetectorROGeometry.hh"
#include "IORTDetectorMessenger.hh"
#include "IORTDetectorSD.hh"
#include "IORTMatrix.hh"
#include "IORTAnalysisManager.hh"
#include "G4Tubs.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4PSDoseDeposit3D.hh"
#include "IORTDetectorMessenger.hh"
/////////////////////////////////////////////////////////////////////////////
IORTDetectorConstruction::IORTDetectorConstruction(G4VPhysicalVolume* physicalTreatmentRoom)
: motherPhys(physicalTreatmentRoom), // pointer to WORLD volume
detectorSD(0), detectorROGeometry(0), matrix(0),
phantom(0), detector(0),
phantomLogicalVolume(0), detectorLogicalVolume(0),
phantomPhysicalVolume(0), detectorPhysicalVolume(0),
@@ -89,7 +86,6 @@ IORTDetectorConstruction::IORTDetectorConstruction(G4VPhysicalVolume* physicalTr
physiDiscoIORT1(0)
{
IORTAnalysisManager::GetInstance();
/* NOTE! that the IORTDetectorConstruction class
* does NOT inherit from G4VUserDetectorConstruction G4 class
@@ -100,54 +96,58 @@ IORTDetectorConstruction::IORTDetectorConstruction(G4VPhysicalVolume* physicalTr
// Messenger to change parameters of the phantom/detector geometry
detectorMessenger = new IORTDetectorMessenger(this);
// Default detector voxels size
// 200 slabs along the beam direction (X)
sizeOfVoxelAlongX = 0.5 *CLHEP::mm; //
sizeOfVoxelAlongY = 0.5 *CLHEP::mm; //
sizeOfVoxelAlongZ = 0.5 *CLHEP::mm; //
// Define here the material of the water phantom and of the detector
SetPhantomMaterial("G4_WATER");
// Construct geometry (messenger commands)
SetDetectorSize(7.*CLHEP::cm, 15.*CLHEP::cm, 15.*CLHEP::cm);
SetPhantomSize(20. *CLHEP::cm, 20. *CLHEP::cm, 20. *CLHEP::cm);
SetPhantomPosition(G4ThreeVector(4.5 *CLHEP::cm, 0. *CLHEP::cm, 0. *CLHEP::cm));
SetDetectorToPhantomPosition(G4ThreeVector(0. *CLHEP::cm, 2.5 *CLHEP::cm, 2.5 *CLHEP::cm));
// Detector
// Default detector sizes
detectorSizeX = 7.* cm;
detectorSizeY = 15.* cm;
detectorSizeZ = 15.* cm;
SetDetectorSize(detectorSizeX, detectorSizeY, detectorSizeZ);
// Phantom
SetPhantomSize(20. *cm, 20. *cm, 20. *cm);
SetPhantomPosition(G4ThreeVector(4.5 *cm, 0. *cm, 0. *cm));
SetDetectorToPhantomPosition(G4ThreeVector(0. *cm, 2.5 *cm, 2.5 *cm));
// Default protection disc geometry and materials
SetOuterRadiusDiscoIORT (40. *CLHEP::mm);
SetinnerRadiusDiscoIORT (0.*CLHEP::mm);
SetheightDiscoIORT (2.0*CLHEP::mm);
SetDiscoXPositionIORT (-11.0*CLHEP::mm);
SetDiscoYPositionIORT (0.0*CLHEP::mm);
SetDiscoZPositionIORT (0.0*CLHEP::mm);
SetOuterRadiusDiscoIORT (40. *mm);
SetinnerRadiusDiscoIORT (0.*mm);
SetheightDiscoIORT (2.0*mm);
SetDiscoXPositionIORT (-11.0*mm);
SetDiscoYPositionIORT (0.0*mm);
SetDiscoZPositionIORT (0.0*mm);
SetDiscoMaterialIORT("G4_WATER");
SetOuterRadiusDiscoIORT1 (40. *CLHEP::mm);
SetinnerRadiusDiscoIORT1 (0.*CLHEP::mm);
SetheightDiscoIORT1 (1.0*CLHEP::mm);
SetDiscoXPositionIORT1 (-8.0*CLHEP::mm);
SetOuterRadiusDiscoIORT1 (40. *mm);
SetinnerRadiusDiscoIORT1 (0.*mm);
SetheightDiscoIORT1 (1.0*mm);
SetDiscoXPositionIORT1 (-8.0*mm);
SetDiscoMaterialIORT1("G4_WATER");
SetAngleDiscoIORT0 (90.0 *CLHEP::deg);
SetAngleDiscoIORT0 (90.0 *deg);
// Write virtual parameters to the real ones and check for consistency
UpdateGeometry();
UpdateGeometry();
}
/////////////////////////////////////////////////////////////////////////////
IORTDetectorConstruction::~IORTDetectorConstruction()
{
delete detectorROGeometry;
delete matrix;
delete detectorMessenger;
}
/////////////////////////////////////////////////////////////////////////////
// ConstructPhantom() is the method that reconstuct a water box (called phantom
// (or water phantom) in the usual Medical physicists slang).
// (or water phantom)).
// A water phantom can be considered a good
// approximation of a an human body.
////////////////////////////////////////////////////////////////////////////
void IORTDetectorConstruction::ConstructPhantom()
{
// Definition of the solid volume of the Phantom
@@ -201,6 +201,7 @@ void IORTDetectorConstruction::ConstructPhantom()
// The detector is the volume that can be dived in slices or voxelized
// and in it we can collect a number of usefull information:
// dose distribution, fluence distribution, LET and so on
void IORTDetectorConstruction::ConstructDetector()
{
@@ -224,19 +225,10 @@ void IORTDetectorConstruction::ConstructDetector()
false,0);
// Visualisation attributes of the detector
//skyBlue = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
G4VisAttributes * skyBlue1 = new G4VisAttributes( G4Colour(135/255. , 206/255. , 235/255. ));
//skyBlue1 -> SetForceWireframe(true);
//skyBlue1 -> SetForceSolid(true);
//skyBlue -> SetVisibility(true);
//skyBlue -> SetForceSolid(true);
//skyBlue -> SetForceWireframe(false);
//detectorLogicalVolume -> SetVisAttributes(skyBlue);
detectorLogicalVolume -> SetVisAttributes(skyBlue1);
// detectorLogicalVolume -> SetVisAttributes(G4VisAttributes::GetInvisible());
// **************
// Cut per Region
// **************
@@ -249,7 +241,8 @@ void IORTDetectorConstruction::ConstructDetector()
detectorLogicalVolume -> SetRegion(aRegion);
aRegion -> AddRootLogicalVolume(detectorLogicalVolume);
}
G4cout << "The Detector has been built --- Add a scoring mesh for it in the GUI if appropriate (similar to the phantom one)" << G4endl;
}
void IORTDetectorConstruction::ConstructDisc()
@@ -257,10 +250,8 @@ void IORTDetectorConstruction::ConstructDisc()
// ---------------------------------------------------------------//
// 6.0 mm Protection Discs Volume //
// ---------------------------------------------------------------//
const G4double startAngleDiscoIORT0 = 0.*CLHEP::deg;
const G4double spanningAngleDiscoIORT0 = 360.*CLHEP::deg;
//G4double phi0 = 180. *CLHEP::deg; // messenger
const G4double startAngleDiscoIORT0 = 0.*deg;
const G4double spanningAngleDiscoIORT0 = 360.*deg;
// Matrix definition for a rotation (deg).
G4RotationMatrix rm0;
@@ -299,23 +290,16 @@ void IORTDetectorConstruction::ConstructDisc()
gray1-> SetVisibility(true);
//gray1 -> SetForceWireframe(true);
//gray1-> SetForceSolid(true);
// const G4double OuterRadiusDiscoIORT = 35. *CLHEP::mm; // messenger
// const G4double innerRadiusDiscoIORT = 0.*CLHEP::mm; // messenger
// const G4double heightDiscoIORT = 3.0*CLHEP::mm; // messenger
const G4double startAngleDiscoIORT = 0.*CLHEP::deg;
const G4double spanningAngleDiscoIORT = 360.*CLHEP::deg;
// const G4double DiscoXPositionIORT = -14.0*CLHEP::mm; // messenger
//G4Material* DiscoMaterialIORT = G4NistManager::Instance()->FindOrBuildMaterial("G4_PLEXIGLASS", isotopes);// messenger
const G4double startAngleDiscoIORT = 0.*deg;
const G4double spanningAngleDiscoIORT = 360.*deg;
G4double phi = 0. *CLHEP::deg;
G4double phi = 0. *deg;
// Matrix definition for a 90 deg rotation. Also used for other volumes
G4RotationMatrix rm;
rm.rotateY(phi);
solidDiscoIORT = new G4Tubs("DiscoIORT", innerRadiusDiscoIORT,
OuterRadiusDiscoIORT,
heightDiscoIORT,
@@ -334,16 +318,9 @@ void IORTDetectorConstruction::ConstructDisc()
// ---------------------------------------------------------------//
// 2.0 mm Lead Protection Disc //
// ---------------------------------------------------------------//
// const G4double OuterRadiusDiscoIORT1 = 35. *CLHEP::mm;
// const G4double innerRadiusDiscoIORT1 = 0.*CLHEP::mm;
// const G4double heightDiscoIORT1 = 0.5*CLHEP::mm;
const G4double startAngleDiscoIORT1 = 0.*CLHEP::deg;
const G4double spanningAngleDiscoIORT1 = 360.*CLHEP::deg;
// const G4double DiscoXPositionIORT1 = -10.5*CLHEP::mm; messenger
// G4Material* DiscoMaterialIORT1 = G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu", isotopes);// messenger
const G4double startAngleDiscoIORT1 = 0.*deg;
const G4double spanningAngleDiscoIORT1 = 360.*deg;
solidDiscoIORT1 = new G4Tubs("DiscoIORT1", innerRadiusDiscoIORT1,
OuterRadiusDiscoIORT1,
@@ -364,47 +341,6 @@ void IORTDetectorConstruction::ConstructDisc()
}
/////////////////////////////////////////////////////////////////////////////
void IORTDetectorConstruction::ConstructSensitiveDetector(G4ThreeVector detectorToWorldPosition)
{
// Install new Sensitive Detector and ROGeometry
delete detectorROGeometry; // this should be safe in C++ also if we have a NULL pointer
//if (detectorSD) detectorSD->PrintAll();
//delete detectorSD;
// Sensitive Detector and ReadOut geometry definition
G4SDManager* sensitiveDetectorManager = G4SDManager::GetSDMpointer();
static G4String sensitiveDetectorName = "Detector";
if (!detectorSD)
{
// The sensitive detector is instantiated
detectorSD = new IORTDetectorSD(sensitiveDetectorName);
}
// The Read Out Geometry is instantiated
static G4String ROGeometryName = "DetectorROGeometry";
detectorROGeometry = new IORTDetectorROGeometry(ROGeometryName,
detectorToWorldPosition,
detectorSizeX/2, // controllare che sia necessario /2
detectorSizeY/2, // CONFERMATO!!! ci vuole!!!
detectorSizeZ/2,
numberOfVoxelsAlongX,
numberOfVoxelsAlongY,
numberOfVoxelsAlongZ);
G4cout << "Instantiating new Read Out Geometry \"" << ROGeometryName << "\""<< G4endl;
// This will invoke Build() IORTDetectorROGeometry virtual method
detectorROGeometry -> BuildROGeometry();
// Attach ROGeometry to SDetector
detectorSD -> SetROgeometry(detectorROGeometry);
//sensitiveDetectorManager -> Activate(sensitiveDetectorName, true);
if (!sensitiveDetectorManager -> FindSensitiveDetector(sensitiveDetectorName, false))
{
G4cout << "Registering new DetectorSD \"" << sensitiveDetectorName << "\""<< G4endl;
// Register user SD
sensitiveDetectorManager -> AddNewDetector(detectorSD);
// Attach SD to detector logical volume
detectorLogicalVolume -> SetSensitiveDetector(detectorSD);
}
}
void IORTDetectorConstruction::ParametersCheck()
{
// Check phantom/detector sizes & relative position
@@ -417,20 +353,8 @@ void IORTDetectorConstruction::ParametersCheck()
detectorToPhantomPosition
))
G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0001", FatalException, "Error: Detector is not fully inside Phantom!");
// Check Detector sizes respect to the voxel ones
if ( detectorSizeX < sizeOfVoxelAlongX) {
G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0002", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel X");
}
if ( detectorSizeY < sizeOfVoxelAlongY) {
G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0003", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel Y");
}
if ( detectorSizeZ < sizeOfVoxelAlongZ) {
G4Exception("IORTDetectorConstruction::ParametersCheck()", "IORT0004", FatalException, "Error: Detector X size must be bigger or equal than that of Voxel Z");
}
}
/////////////////
// MESSENGERS //
////////////////
@@ -530,15 +454,12 @@ void IORTDetectorConstruction::SetDetectorSize(G4double sizeX, G4double sizeY, G
if (sizeX > 0.) {detectorSizeX = sizeX;}
if (sizeY > 0.) {detectorSizeY = sizeY;}
if (sizeZ > 0.) {detectorSizeZ = sizeZ;}
SetVoxelSize(sizeOfVoxelAlongX, sizeOfVoxelAlongY, sizeOfVoxelAlongZ);
}
/////////////////////////////////////////////////////////////////////////////
void IORTDetectorConstruction::SetVoxelSize(G4double sizeX, G4double sizeY, G4double sizeZ)
void IORTDetectorConstruction::SetVoxelSize(G4double , G4double , G4double)
{
if (sizeX > 0.) {sizeOfVoxelAlongX = sizeX;}
if (sizeY > 0.) {sizeOfVoxelAlongY = sizeY;}
if (sizeZ > 0.) {sizeOfVoxelAlongZ = sizeZ;}
G4cout<< "SetVoxelSize method is not needed anymore " << G4endl;
}
void IORTDetectorConstruction::SetPhantomPosition(G4ThreeVector pos)
{
@@ -560,7 +481,7 @@ void IORTDetectorConstruction::SetOuterRadiusDiscoIORT(G4double outerr)
void IORTDetectorConstruction::SetinnerRadiusDiscoIORT(G4double innerr)
{
if (innerr > 0.) {innerRadiusDiscoIORT = innerr;}
if (innerr >= 0.) {innerRadiusDiscoIORT = innerr;}
}
@@ -599,7 +520,7 @@ void IORTDetectorConstruction::SetOuterRadiusDiscoIORT1(G4double outerr)
void IORTDetectorConstruction::SetinnerRadiusDiscoIORT1(G4double innerr)
{
if (innerr > 0.) {innerRadiusDiscoIORT1 = innerr;}
if (innerr >= 0.) {innerRadiusDiscoIORT1 = innerr;}
}
@@ -654,38 +575,19 @@ void IORTDetectorConstruction::UpdateGeometry()
else ConstructDetector();
// update disc function
delete solidDiscoIORT0;
delete logicDiscoIORT0;
delete physiDiscoIORT0;
delete solidDiscoIORT;
delete logicDiscoIORT;
delete physiDiscoIORT;
delete solidDiscoIORT1;
delete logicDiscoIORT1;
delete physiDiscoIORT1;
if (physiDiscoIORT1) delete physiDiscoIORT1;
if (logicDiscoIORT1) delete logicDiscoIORT1;
if (solidDiscoIORT1) delete solidDiscoIORT1;
if (physiDiscoIORT) delete physiDiscoIORT;
if (logicDiscoIORT) delete logicDiscoIORT;
if (solidDiscoIORT) delete solidDiscoIORT;
if (physiDiscoIORT0) delete physiDiscoIORT0;
if (logicDiscoIORT0) delete logicDiscoIORT0;
if (solidDiscoIORT0) delete solidDiscoIORT0;
ConstructDisc();
// Round to nearest integer number of voxel
numberOfVoxelsAlongX = G4lrint(detectorSizeX / sizeOfVoxelAlongX);
sizeOfVoxelAlongX = ( detectorSizeX / numberOfVoxelsAlongX );
numberOfVoxelsAlongY = G4lrint(detectorSizeY / sizeOfVoxelAlongY);
sizeOfVoxelAlongY = ( detectorSizeY / numberOfVoxelsAlongY );
numberOfVoxelsAlongZ = G4lrint(detectorSizeZ / sizeOfVoxelAlongZ);
sizeOfVoxelAlongZ = ( detectorSizeZ / numberOfVoxelsAlongZ );
//G4cout << "*************** DetectorToWorldPosition " << GetDetectorToWorldPosition()/cm << "\n";
ConstructSensitiveDetector(GetDetectorToWorldPosition());
volumeOfVoxel = sizeOfVoxelAlongX * sizeOfVoxelAlongY * sizeOfVoxelAlongZ;
massOfVoxel = detectorMaterial -> GetDensity() * volumeOfVoxel;
// This will clear the existing matrix (together with all data inside it)!
matrix = IORTMatrix::GetInstance(numberOfVoxelsAlongX,
numberOfVoxelsAlongY,
numberOfVoxelsAlongZ,
massOfVoxel);
// Inform the kernel about the new geometry
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
@@ -695,18 +597,21 @@ void IORTDetectorConstruction::UpdateGeometry()
}
void IORTDetectorConstruction::DeleteDisc()
{
delete solidDiscoIORT0;
delete logicDiscoIORT0;
delete physiDiscoIORT0;
delete solidDiscoIORT;
delete logicDiscoIORT;
delete physiDiscoIORT;
delete solidDiscoIORT1;
delete logicDiscoIORT1;
delete physiDiscoIORT1;
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
{
if (physiDiscoIORT1) delete physiDiscoIORT1;
if (logicDiscoIORT1) delete logicDiscoIORT1;
if (solidDiscoIORT1) delete solidDiscoIORT1;
if (physiDiscoIORT) delete physiDiscoIORT;
if (logicDiscoIORT) delete logicDiscoIORT;
if (solidDiscoIORT) delete solidDiscoIORT;
if (physiDiscoIORT0) delete physiDiscoIORT0;
if (logicDiscoIORT0) delete logicDiscoIORT0;
if (solidDiscoIORT0) delete solidDiscoIORT0;
G4RunManager::GetRunManager() -> GeometryHasBeenModified();
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
}
@@ -727,15 +632,5 @@ void IORTDetectorConstruction::PrintParameters()
G4cout << "DX= "<< G4BestUnit(phantomPosition.getX(),"Length") <<
"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;
G4cout << "The number of Voxels along (X,Y,Z) is: (" <<
numberOfVoxelsAlongX << ',' <<
numberOfVoxelsAlongY <<',' <<
numberOfVoxelsAlongZ << ')' << G4endl;
}
@@ -1,77 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTDetectorHit.hh"
G4Allocator<IORTDetectorHit> IORTDetectorHitAllocator;
IORTDetectorHit::IORTDetectorHit()
{
energyDeposit = 0;
}
IORTDetectorHit::~IORTDetectorHit()
{
}
IORTDetectorHit::IORTDetectorHit(const IORTDetectorHit &right)
: G4VHit()
{
xHitID = right.xHitID;
zHitID = right.zHitID;
yHitID = right.yHitID;
energyDeposit = right.energyDeposit;
}
const IORTDetectorHit& IORTDetectorHit::operator=(const IORTDetectorHit &right)
{
xHitID = right.xHitID;
zHitID = right.zHitID;
yHitID = right.yHitID;
energyDeposit = right.energyDeposit;
return *this;
}
int IORTDetectorHit::operator==(const IORTDetectorHit &right) const
{
return((xHitID==right.xHitID)&&(zHitID==right.zHitID)&&(yHitID==right.yHitID));
}
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -1,206 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTDetectorROGeometry.hh"
#include "IORTDummySD.hh"
#include "G4SystemOfUnits.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4PVReplica.hh"
#include "G4Box.hh"
#include "G4ThreeVector.hh"
#include "G4Material.hh"
/////////////////////////////////////////////////////////////////////////////
IORTDetectorROGeometry::IORTDetectorROGeometry(G4String aString, G4ThreeVector pos,
G4double detectorDimX,
G4double detectorDimY,
G4double detectorDimZ,
G4int numberOfVoxelsX,
G4int numberOfVoxelsY,
G4int numberOfVoxelsZ):
G4VReadOutGeometry(aString),
detectorToWorldPosition(pos),
detectorSizeX(detectorDimX),
detectorSizeY(detectorDimY),
detectorSizeZ(detectorDimZ),
numberOfVoxelsAlongX(numberOfVoxelsX),
numberOfVoxelsAlongY(numberOfVoxelsY),
numberOfVoxelsAlongZ(numberOfVoxelsZ)
{
}
/////////////////////////////////////////////////////////////////////////////
IORTDetectorROGeometry::~IORTDetectorROGeometry()
{
}
/////////////////////////////////////////////////////////////////////////////
G4VPhysicalVolume* IORTDetectorROGeometry::Build()
{
// A dummy material is used to fill the volumes of the readout geometry.
// (It will be allowed to set a NULL pointer in volumes of such virtual
// division in future, since this material is irrelevant for tracking.)
G4Material* dummyMat = new G4Material(name="dummyMat", 1., 1.*g/mole, 1.*g/cm3);
G4double worldSizeX = 400.0 *cm; // 200.0 *cm;
G4double worldSizeY = 400.0 *cm; // 200.0 *cm;
G4double worldSizeZ = 400.0 *cm; // 200.0 *cm;
G4double halfDetectorSizeX = detectorSizeX;
G4double halfDetectorSizeY = detectorSizeY;
G4double halfDetectorSizeZ = detectorSizeZ;
// World volume of ROGeometry ...
G4Box* ROWorld = new G4Box("ROWorld",
worldSizeX,
worldSizeY,
worldSizeZ);
G4LogicalVolume* ROWorldLog = new G4LogicalVolume(ROWorld, dummyMat,
"ROWorldLog", 0,0,0);
G4VPhysicalVolume* ROWorldPhys = new G4PVPlacement(0,G4ThreeVector(),
"ROWorldPhys",
ROWorldLog,
0,false,0);
// Detector ROGeometry
G4Box *RODetector = new G4Box("RODetector",
halfDetectorSizeX,
halfDetectorSizeY,
halfDetectorSizeZ);
G4LogicalVolume *RODetectorLog = new G4LogicalVolume(RODetector,
dummyMat,
"RODetectorLog",
0,0,0);
G4VPhysicalVolume *RODetectorPhys = new G4PVPlacement(0,
detectorToWorldPosition,
"DetectorPhys",
RODetectorLog,
ROWorldPhys,
false,0);
// Division along X axis: the detector is divided in slices along the X axis
G4double halfXVoxelSizeX = halfDetectorSizeX/numberOfVoxelsAlongX;
G4double halfXVoxelSizeY = halfDetectorSizeY;
G4double halfXVoxelSizeZ = halfDetectorSizeZ;
G4double voxelXThickness = 2*halfXVoxelSizeX;
G4Box *RODetectorXDivision = new G4Box("RODetectorXDivision",
halfXVoxelSizeX,
halfXVoxelSizeY,
halfXVoxelSizeZ);
G4LogicalVolume *RODetectorXDivisionLog = new G4LogicalVolume(RODetectorXDivision,
dummyMat,
"RODetectorXDivisionLog",
0,0,0);
G4VPhysicalVolume *RODetectorXDivisionPhys = new G4PVReplica("RODetectorXDivisionPhys",
RODetectorXDivisionLog,
RODetectorPhys,
kXAxis,
numberOfVoxelsAlongX,
voxelXThickness);
// Division along Y axis: the slices along the X axis are divided along the Y axis
G4double halfYVoxelSizeX = halfXVoxelSizeX;
G4double halfYVoxelSizeY = halfDetectorSizeY/numberOfVoxelsAlongY;
G4double halfYVoxelSizeZ = halfDetectorSizeZ;
G4double voxelYThickness = 2*halfYVoxelSizeY;
G4Box *RODetectorYDivision = new G4Box("RODetectorYDivision",
halfYVoxelSizeX,
halfYVoxelSizeY,
halfYVoxelSizeZ);
G4LogicalVolume *RODetectorYDivisionLog = new G4LogicalVolume(RODetectorYDivision,
dummyMat,
"RODetectorYDivisionLog",
0,0,0);
G4VPhysicalVolume *RODetectorYDivisionPhys = new G4PVReplica("RODetectorYDivisionPhys",
RODetectorYDivisionLog,
RODetectorXDivisionPhys,
kYAxis,
numberOfVoxelsAlongY,
voxelYThickness);
// Division along Z axis: the slices along the Y axis are divided along the Z axis
G4double halfZVoxelSizeX = halfXVoxelSizeX;
G4double halfZVoxelSizeY = halfYVoxelSizeY;
G4double halfZVoxelSizeZ = halfDetectorSizeZ/numberOfVoxelsAlongZ;
G4double voxelZThickness = 2*halfZVoxelSizeZ;
G4Box *RODetectorZDivision = new G4Box("RODetectorZDivision",
halfZVoxelSizeX,
halfZVoxelSizeY,
halfZVoxelSizeZ);
G4LogicalVolume *RODetectorZDivisionLog = new G4LogicalVolume(RODetectorZDivision,
dummyMat,
"RODetectorZDivisionLog",
0,0,0);
RODetectorZDivisionPhys = new G4PVReplica("RODetectorZDivisionPhys",
RODetectorZDivisionLog,
RODetectorYDivisionPhys,
kZAxis,
numberOfVoxelsAlongZ,
voxelZThickness);
IORTDummySD *dummySD = new IORTDummySD;
RODetectorZDivisionLog -> SetSensitiveDetector(dummySD);
return ROWorldPhys;
}
@@ -1,205 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTDetectorSD.hh"
#include "IORTAnalysisManager.hh"
#include "IORTDetectorHit.hh"
#include "G4Step.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include "G4SDManager.hh"
#include "IORTMatrix.hh"
#include "G4SystemOfUnits.hh"
/////////////////////////////////////////////////////////////////////////////
IORTDetectorSD::IORTDetectorSD(G4String dname):
G4VSensitiveDetector(dname)
{
G4String HCname;
collectionName.insert(HCname="IORTDetectorHitsCollection");
HitsCollection = NULL;
sensitiveDetectorName = dname;
}
/////////////////////////////////////////////////////////////////////////////
IORTDetectorSD::~IORTDetectorSD()
{
}
/////////////////////////////////////////////////////////////////////////////
void IORTDetectorSD::Initialize(G4HCofThisEvent*)
{
HitsCollection = new IORTDetectorHitsCollection(sensitiveDetectorName,
collectionName[0]);
}
/////////////////////////////////////////////////////////////////////////////
G4bool IORTDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* ROhist)
{
//The code doesn't seem to get here if we use the IAEA geometry. FIXME
if(!ROhist)
return false;
if (aStep -> GetPreStepPoint() -> GetPhysicalVolume() -> GetName() != "DetectorPhys")
return false;
// Get kinetic energy
G4Track * theTrack = aStep -> GetTrack();
//G4double kineticEnergy = theTrack -> GetKineticEnergy();
G4ParticleDefinition *particleDef = theTrack -> GetDefinition();
//Get particle name
G4String particleName = particleDef -> GetParticleName();
// G4cout << particleDef -> GetParticleType() << '\n';
// Get unique track_id (in an event)
G4int trackID = theTrack -> GetTrackID();
G4double energyDeposit = aStep -> GetTotalEnergyDeposit();
G4int Z = particleDef-> GetAtomicNumber();
//G4int A = particleDef-> GetAtomicMass();
// Read voxel indexes: i is the x index, k is the z index
G4int k = ROhist -> GetReplicaNumber(0);
G4int i = ROhist -> GetReplicaNumber(2);
G4int j = ROhist -> GetReplicaNumber(1);
IORTAnalysisManager* analysis = IORTAnalysisManager::GetInstance();
IORTMatrix* matrix = IORTMatrix::GetInstance();
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);
/*
// 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);
}
*/
}
if(energyDeposit != 0)
{
/*
* This method will fill a dose matrix for every single nuclide.
* A method of the IORTMatrix 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
*/
IORTDetectorHit* detectorHit = new IORTDetectorHit();
detectorHit -> SetEdepAndPosition(i, j, k, energyDeposit);
HitsCollection -> insert(detectorHit);
}
}
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);
}
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
void IORTDetectorSD::EndOfEvent(G4HCofThisEvent* HCE)
{
static G4int HCID = -1;
if(HCID < 0)
{
HCID = GetCollectionID(0);
}
HCE -> AddHitsCollection(HCID,HitsCollection);
}
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -41,33 +41,24 @@
#include "G4SystemOfUnits.hh"
#include "G4Event.hh"
#include "G4EventManager.hh"
#include "G4HCofThisEvent.hh"
#include "G4VHitsCollection.hh"
#include "G4SDManager.hh"
#include "G4VVisManager.hh"
#include "IORTEventAction.hh"
#include "IORTDetectorHit.hh"
#include "IORTDetectorSD.hh"
#include "IORTDetectorConstruction.hh"
#include "IORTMatrix.hh"
#include "IORTEventActionMessenger.hh"
/////////////////////////////////////////////////////////////////////////////
IORTEventAction::IORTEventAction() :
drawFlag("all" ),printModulo(1000), pointerEventMessenger(0)
{
hitsCollectionID = -1;
pointerEventMessenger = new IORTEventActionMessenger(this);
}
/////////////////////////////////////////////////////////////////////////////
IORTEventAction::~IORTEventAction()
{
delete pointerEventMessenger;
}
/////////////////////////////////////////////////////////////////////////////
void IORTEventAction::BeginOfEventAction(const G4Event* evt)
{
G4int evtNb = evt->GetEventID();
@@ -75,45 +66,9 @@ void IORTEventAction::BeginOfEventAction(const G4Event* evt)
//printing survey
if (evtNb%printModulo == 0)
G4cout << "\n---> Begin of Event: " << evtNb << G4endl;
G4SDManager* pSDManager = G4SDManager::GetSDMpointer();
if(hitsCollectionID == -1)
hitsCollectionID = pSDManager -> GetCollectionID("IORTDetectorHitsCollection");
}
/////////////////////////////////////////////////////////////////////////////
void IORTEventAction::EndOfEventAction(const G4Event* evt)
{
if(hitsCollectionID < 0)
return;
G4HCofThisEvent* HCE = evt -> GetHCofThisEvent();
// Clear voxels hit list
IORTMatrix* matrix = IORTMatrix::GetInstance();
if (matrix) matrix -> ClearHitTrack();
if(HCE)
{
IORTDetectorHitsCollection* CHC = (IORTDetectorHitsCollection*)(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);
}
}
}
}
}
void IORTEventAction::EndOfEventAction(const G4Event*)
{}
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,14 +33,13 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTGeometryController.hh"
#include "IORTDetectorConstruction.hh"
#include "IORTInteractionParameters.hh"
#include "Collimator40BeamLine.hh"
#include "Collimator50BeamLine.hh"
#include "Collimator60BeamLine.hh"
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -1,295 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include <fstream>
#include <iostream>
#include <sstream>
#include <cmath>
#include <vector>
#include "IORTInteractionParameters.hh"
#include "IORTParameterMessenger.hh"
#include "IORTDetectorConstruction.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4UImanager.hh"
#include "G4RunManager.hh"
#include "G4LossTableManager.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4NistManager.hh"
#include "G4Element.hh"
#include "G4StateManager.hh"
IORTInteractionParameters::IORTInteractionParameters(G4bool wantMessenger):
nistEle(new G4NistElementBuilder(0)),
nistMat(new G4NistMaterialBuilder(nistEle, 0)),
data(G4cout.rdbuf()),
pMessenger(0),
beamFlag(false)
#ifdef G4ANALYSIS_USE_ROOT
,theRootCanvas(0),
theRootGraph(0)
#endif
{
if (wantMessenger) pMessenger = new IORTParameterMessenger(this);
}
IORTInteractionParameters::~IORTInteractionParameters()
{
if (pMessenger) delete pMessenger;
delete nistMat;
delete nistEle;
}
G4double IORTInteractionParameters::GetStopping (G4double ene,
const G4ParticleDefinition* pDef,
const G4Material* pMat,
G4double dens)
{
if (dens) return ComputeTotalDEDX(ene, pDef, pMat)/dens;
return ComputeTotalDEDX(ene, pDef, pMat);
}
bool IORTInteractionParameters::GetStoppingTable(const G4String& vararg)
{
// Check arguments
if ( !ParseArg(vararg)) return false;
// Clear previous energy & mass sp vectors
energy.clear();
massDedx.clear();
// log scale
if (kinEmin != kinEmax && npoints >1)
{
G4double logmin = std::log10(kinEmin);
G4double logmax = std::log10(kinEmax);
G4double en;
// uniform log space
for (G4double c = 0.; c < npoints; c++)
{
en = std::pow(10., logmin + ( c*(logmax-logmin) / (npoints - 1.)) );
energy.push_back(en/MeV);
dedxtot = ComputeTotalDEDX (en, particle, material);
massDedx.push_back ( (dedxtot / density)/(MeV*cm2/g) );
}
}
else // one point only
{
energy.push_back(kinEmin/MeV);
dedxtot = ComputeTotalDEDX (kinEmin, particle, material);
massDedx.push_back ( (dedxtot / density)/(MeV*cm2/g) );
}
G4cout.precision(6);
data << "MeV " << "MeV*cm2/g " << particle << " (into " <<
material << ", density = " << G4BestUnit(density,"Volumic Mass") << ")" << G4endl;
data << G4endl;
data << std::left << std::setfill(' ');
for (size_t i=0; i<energy.size(); i++){
data << std::setw(16) << energy[i] << massDedx[i] << G4endl;
}
outfile.close();
// This will plot
#ifdef G4ANALYSIS_USE_ROOT
PlotStopping("pdf");
#endif
// Info to user
G4String ofName = (filename == "") ? "User terminal": filename;
G4cout << "User choice:\n";
G4cout << "Kinetic energy lower limit= "<< G4BestUnit(kinEmin,"Energy") <<
", Kinetic energy upper limit= " << G4BestUnit(kinEmax,"Energy") <<
", npoints= "<< npoints << ", particle= \"" << particle <<
"\", material= \"" << material << "\", filename= \""<<
ofName << "\"" << G4endl;
return true;
}
///////////////////////////////////////////////////////////////////////////////////
// Save Plot
#ifdef G4ANALYSIS_USE_ROOT
void IORTInteractionParameters::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* IORTInteractionParameters::GetNistMaterial(G4String mat)
{
Pmaterial = G4NistManager::Instance()->FindOrBuildMaterial(mat);
if (Pmaterial) density = Pmaterial -> GetDensity();
return Pmaterial;
}
// Parse arguments line
bool IORTInteractionParameters::ParseArg(const G4String& vararg)
{
kinEmin = kinEmax = npoints = 0.;
particle = material = filename = "";
// set internal variables
std::istringstream strParam(vararg);
// TODO here check for number and parameters consistency
strParam >> std::skipws >> material >> kinEmin >> kinEmax >> npoints >> particle >> filename;
// npoints must be an integer!
npoints = std::floor(npoints);
// Check that kinEmax >= kinEmin > 0 && npoints >= 1
// TODO NIST points and linear scale
if (kinEmax == 0. && kinEmin > 0. ) kinEmax = kinEmin;
if (kinEmax == 0. && kinEmin == 0. ) kinEmax = kinEmin = 1.*MeV;
if (kinEmax < kinEmin)
{
G4cout << "WARNING: kinEmin must not exceed kinEmax!" << G4endl;
G4cout << "Usage: /parameter/command material kinetic Emin kinetic Emax nPoints [particle] [output filename]" << G4endl;
return false;
}
if (npoints < 1) npoints = 1;
// check if element/material is into database
if (!GetNistMaterial(material) )
{
G4cout << "WARNING: material \"" << material << "\" doesn't exist in NIST elements/materials"
" table [$G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc]" << G4endl;
G4cout << "Use command \"/parameter/nist\" to see full materials list" << G4endl;
return false;
}
// Check for particle
if (particle == "") particle = "proton"; // default to "proton"
else if ( !FindParticle(particle) )
{
G4cout << "WARNING: Particle \"" << particle << "\" isn't supported." << G4endl;
G4cout << "Try the command \"/particle/list\" to get full supported particles list." << G4endl;
G4cout << "If you are interested in an ion that isn't in this list you must give it to the particle gun."
"\nTry the commands:\n/gun/particle ion"
"\n/gun/ion <atomic number> <mass number> <[charge]>" << G4endl << G4endl;
return false;
}
// start physics by forcing a G4RunManager::BeamOn():
BeamOn();
// Set output file
if( filename != "" )
{
outfile.open(filename,std::ios_base::trunc); // overwrite existing file
data.rdbuf(outfile.rdbuf());
}
else data.rdbuf(G4cout.rdbuf()); // output is G4cout!
return true;
}
// Force physics tables build
void IORTInteractionParameters::BeamOn()
{
// first check if RunManager is above G4State_Idle
G4StateManager* mState = G4StateManager::GetStateManager();
G4ApplicationState aState = mState -> GetCurrentState();
if ( aState <= G4State_Idle && beamFlag == false)
{
G4cout << "Issuing a G4RunManager::beamOn()... ";
G4cout << "Current Run State is " << mState -> GetStateString( aState ) << G4endl;
G4RunManager::GetRunManager() -> BeamOn(0);
beamFlag = true;
}
}
// print a list of Nist elements and materials
void IORTInteractionParameters::ListOfNistMaterials(const G4String& vararg)
{
/*
$G4INSTALL/source/materials/src/G4NistElementBuilder.cc
You can also construct a new material by the ConstructNewMaterial method:
see $G4INSTALL/source/materials/src/G4NistMaterialBuilder.cc
*/
// Get simplest full list
if (vararg =="list")
{
const std::vector<G4String>& vec = nistMat -> GetMaterialNames();
for (size_t i=0; i<vec.size(); i++)
{
G4cout << std::setw(12) << std::left << i+1 << vec[i] << G4endl;
}
G4cout << G4endl;
}
else if (vararg =="all" || vararg =="simple" ||
vararg =="compound" || vararg =="hep" )
{
nistMat -> ListMaterials(vararg);
}
}
@@ -1,403 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include "IORTMatrix.hh"
#include "IORTAnalysisManager.hh"
#include "IORTPrimaryGeneratorAction.hh"
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
#include "G4ParticleGun.hh"
// Units definition: CLHEP/Units/SystemOfUnits.h
//
IORTMatrix* IORTMatrix::instance = NULL;
G4bool IORTMatrix::secondary = false;
// Only return a pointer to matrix
IORTMatrix* IORTMatrix::GetInstance()
{
return instance;
}
// This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it
// TODO A check on the parameters is required!
IORTMatrix* IORTMatrix::GetInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass)
{
if (instance) delete instance;
instance = new IORTMatrix(voxelX, voxelY, voxelZ, mass);
instance -> Initialize();
return instance;
}
IORTMatrix::IORTMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass):
stdFile("Dose.out"),
doseUnit(MeV/g)
{
// 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 << "IORTMatrix: Memory space to store physical dose into " <<
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated " << G4endl;
}
else G4Exception("IORTMatrix::IORTMatrix()", "IORT0005", FatalException, "Error: 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();
}
/////////////////////////////////////////////////////////////////////////////
IORTMatrix::~IORTMatrix()
{
delete[] matrix;
delete[] hitTrack;
// free fluences/dose data memory
Clear();
}
/////////////////////////////////////////////////////////////////////////////
void IORTMatrix::Clear()
{
for (size_t i=0; i<ionStore.size(); i++)
{
delete[] ionStore[i].dose;
delete[] ionStore[i].fluence;
}
ionStore.clear();
}
/////////////////////////////////////////////////////////////////////////////
// Initialise the elements of the matrix to zero
void IORTMatrix::Initialize()
{
// Clear ions store
Clear();
// Clear dose
for(int i=0;i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ;i++)
{
matrix[i] = 0;
}
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Print generated nuclides list
void IORTMatrix::PrintNuclides()
{
for (size_t i=0; i<ionStore.size(); i++)
{
G4cout << ionStore[i].name << G4endl;
}
}
/////////////////////////////////////////////////////////////////////////////
// Clear Hit voxel (TrackID) markers
void IORTMatrix::ClearHitTrack()
{
for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0;
}
// Return Hit status
G4int* IORTMatrix::GetHitTrack(G4int i, G4int j, G4int 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)
/////////////////////////////////////////////////////////////////////////////
G4bool IORTMatrix::Fill(G4int trackID,
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
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/massOfVoxel;
// 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 =
{
(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/massOfVoxel;
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;
}
else // XXX Out of memory! XXX
{
return false;
}
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Methods to store data to filenames...
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//
// General method to store matrix data to filename
void IORTMatrix::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();
}
}
}
// Store fluence per single ion in multiple files
void IORTMatrix::StoreFluenceData()
{
for (size_t i=0; i < ionStore.size(); i++){
StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int));
}
}
// Store dose per single ion in multiple files
void IORTMatrix::StoreDoseData()
{
for (size_t i=0; i < ionStore.size(); i++){
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 IORTAnalysisFileMessenger.cc class file
void IORTMatrix::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(MeV/g)";
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();
}
}
/////////////////////////////////////////////////////////////////////////////
void IORTMatrix::StoreDoseFluenceRoot()
{
IORTAnalysisManager* analysis = IORTAnalysisManager::GetInstance();
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] );
}
}
}
void IORTMatrix::Fill(G4int i, G4int j, G4int k,
G4double energyDeposit)
{
if (matrix)
matrix[Index(i,j,k)] += energyDeposit;
// Store the energy deposit in the matrix element corresponding
// to the phantom voxel
}
void IORTMatrix::TotalEnergyDeposit()
{
// Store the information of the matrix in a ntuple and in
// a 1D Histogram
}
@@ -1,97 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTParameterMessenger.hh"
#include "IORTInteractionParameters.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
IORTParameterMessenger::IORTParameterMessenger(IORTInteractionParameters* param)
:pParam(param)
{
paramDir = new G4UIdirectory("/parameter/");
paramDir -> SetGuidance("Commands to generate stopping power and range");
dedxCmd = new G4UIcmdWithAString("/parameter/getstopping",this);
dedxCmd->SetGuidance("Get mass stopping powers"
"\n[usage]: /parameter/getstopping Material [Emin] [Emax] [N] [Particle] [File]"
"\n Material:(string) Material name, like G4_H, G4_WATER,..., look at /parameter/nist"
"\n Emin Emax:(double) minimum and maximum kinetic energy (MeV)"
"\n N:(double) [number of points]"
"\n Particle:(string) Particle name, look at /particle/list"
"\n File:(string) Name for the output file."
"\nDefault values for parameters inside [] are respectively:"
"\n \"1 MeV\", \"Emin\", \"1\", \"proton\", \"stdout\"");
dedxCmd->SetParameterName("inputData",false);
dedxCmd->AvailableForStates(G4State_Idle);
listCmd = new G4UIcmdWithAString("/parameter/nist",this);
listCmd -> SetGuidance("Print NIST elements/materials.\nParameters:"
"\n\t all: will print elements and compounds"
"\n\t simple: will print elements only"
"\n\t compound: will print compounds only"
"\n\t hep: will print hep compounds"
"\n\t list: will print a simple full list of all elements and compounds");
listCmd -> SetParameterName("String",true);
listCmd -> SetDefaultValue("list");
listCmd -> SetCandidates("all simple compound hep list");
listCmd ->AvailableForStates(G4State_Idle);
//Available G4 States (G4State_PreInit, G4State_Init, G4State_Idle,G4State_GeomClosed, G4State_EventProc);
}
IORTParameterMessenger::~IORTParameterMessenger()
{
delete paramDir;
delete dedxCmd;
delete listCmd;
}
void IORTParameterMessenger::SetNewValue(G4UIcommand* command, G4String vararg)
{
if (command == dedxCmd)
{
pParam -> GetStoppingTable(vararg);
}
else if (command == listCmd)
{
pParam -> ListOfNistMaterials(vararg);
}
}
@@ -1,82 +0,0 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// This is the *BASIC* version of IORT, a Geant4-based application
//
// Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
// Contributor Authors: S.Guatelli(e)
// Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
//
// (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTParticles.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4ParticleTable.hh"
#include "G4LeptonConstructor.hh"
#include "G4BosonConstructor.hh"
#include "G4MesonConstructor.hh"
#include "G4BaryonConstructor.hh"
#include "G4ShortLivedConstructor.hh"
#include "G4IonConstructor.hh"
IORTParticles::IORTParticles(const G4String& name)
: G4VPhysicsConstructor(name)
{ }
IORTParticles::~IORTParticles()
{}
void IORTParticles::ConstructParticle()
{
//
// Define all the particles involved in the experimental set-up
//
G4LeptonConstructor lepton;
lepton.ConstructParticle();
G4BosonConstructor boson;
boson.ConstructParticle();
G4MesonConstructor meson;
meson.ConstructParticle();
G4BaryonConstructor baryon;
baryon.ConstructParticle();
G4ShortLivedConstructor shortLived;
shortLived.ConstructParticle();
G4IonConstructor ion;
ion.ConstructParticle();
}
@@ -33,36 +33,12 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Physics models in IORT, following the Geant4 organisation, can be definided using three different approaches:
// 1. Activating one of the 'Reference Physics Lists' that are already prepared by
// the Geant4 Collaboration and are contained in the $G4INSTALL/source/physics_lists/lists folder
// The 'Reference Physics Lists' can be activated setting a specific enviroment variable to the name
// of the physics. For example if the QGSP_BIC Reference Physics Lists must be activated the User
// must set export PHYSLIST=QGSP_BIC (or setenv PHYSLIST QGSP_BIC).
// A 'Reference Physics Lists' contains all the physics process necessary to a particle transport
// If the User set the PHYSLIST variable IORT will start with the defaultMacroWithReferencePhysicsList.mac
// macro. See this macro file for more details
//
// 2. Activating the 'Builders' already prepared by
// the Geant4 Collaboration and contained in the $G4INSTALL/source/physics_lists/builder folder.
// Each builder is specific of a given model. There are builders for the electromagnetic processes, for the
// hadronic one, etc.
// If the PHYSLIST variable is not defined IORT starts with the defaultMacro.mac where the single builders
// are activated for the various processes of interest.
// Each builder is activated with the /Physics/addPhysics <nome builder> command
//
// ****** SUGGESTED PHYSICS *********
//
// AT MOMENT, IF ACCURATE RESULTS ARE NEDED, WE STRONGLY RECOMMEND:
// 1. The use of the emstandard_opt3, or
// 2. the QGSP_BIC_EMY Reference Physics Lists (define the PHYSLIST eviroment variable):
// export PHYSLIST=QGSP_BIC_EMY
#include "G4SystemOfUnits.hh"
#include "G4RunManager.hh"
#include "G4Region.hh"
@@ -70,57 +46,32 @@
#include "IORTPhysicsList.hh"
#include "IORTPhysicsListMessenger.hh"
#include "IORTStepMax.hh"
#include "G4PhysListFactory.hh"
#include "G4VPhysicsConstructor.hh"
// Local physic directly implemented in the Hadronthrapy directory
//#include "LocalIonIonInelasticPhysic.hh" // Physic dedicated to the ion-ion inelastic processes
//#include "LocalINCLIonIonInelasticPhysic.hh" // Physic dedicated to the ion-ion inelastic processes using ////INCL/ABLA
// #include "LocalStandardICRU73EmPhysic.hh" // This permits the use of the ICRU73 tables for stopping powers of ions. AGGIUNTO da eliot_geant4.9.3p01_version
// Physic lists (contained inside the Geant4 source code, in the 'physicslists folder')
#include "G4EmStandardPhysics_option3.hh"
#include "G4EmStandardPhysics_option4.hh"
#include "G4EmLivermorePhysics.hh"
#include "G4EmPenelopePhysics.hh"
#include "G4EmExtraPhysics.hh"
#include "G4StoppingPhysics.hh"
#include "G4DecayPhysics.hh"
#include "G4HadronElasticPhysics.hh"
#include "G4HadronElasticPhysicsHP.hh"
#include "G4HadronDElasticPhysics.hh"
#include "G4HadronHElasticPhysics.hh"
#include "G4HadronInelasticQBBC.hh"
#include "G4IonBinaryCascadePhysics.hh"
#include "G4Decay.hh"
#include "G4DecayPhysics.hh"
#include "G4NeutronTrackingCut.hh"
#include "G4LossTableManager.hh"
#include "G4UnitsTable.hh"
#include "G4ProcessManager.hh"
#include "G4HadronPhysicsQGSP_BIC.hh"
#include "G4IonFluctuations.hh"
#include "G4IonParametrisedLossModel.hh"
#include "G4EmProcessOptions.hh"
#include "G4ParticleDefinition.hh"
#include "G4ProductionCutsTable.hh"
#include "G4ProcessManager.hh"
#include "globals.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
#include "G4Positron.hh"
#include "G4UnitsTable.hh"
#include "G4DecayPhysics.hh"
#include "G4RadioactiveDecayPhysics.hh"
/////////////////////////////////////////////////////////////////////////////
IORTPhysicsList::IORTPhysicsList() : G4VModularPhysicsList()
{
G4LossTableManager::Instance();
defaultCutValue = 0.01 *mm; //1.*mm;
defaultCutValue = 0.1 *mm;
cutForGamma = defaultCutValue;
cutForElectron = defaultCutValue;
cutForPositron = defaultCutValue;
helIsRegistered = false;
bicIsRegistered = false;
biciIsRegistered = false;
locIonIonInelasticIsRegistered = false;
radioactiveDecayIsRegistered = false;
stepMaxProcess = 0;
pMessenger = new IORTPhysicsListMessenger(this);
@@ -128,29 +79,23 @@ IORTPhysicsList::IORTPhysicsList() : G4VModularPhysicsList()
SetVerboseLevel(1);
// EM physics
emPhysicsList = new G4EmStandardPhysics_option3(1);
emName = G4String("emstandard_opt3");
// Decay physics and all particles
emPhysicsList = new G4EmStandardPhysics_option4(1);
emName = G4String("emstandard_opt4");
decPhysicsList = new G4DecayPhysics();
}
/////////////////////////////////////////////////////////////////////////////
IORTPhysicsList::~IORTPhysicsList()
{
delete pMessenger;
delete emPhysicsList;
delete decPhysicsList;
for(size_t i=0; i<hadronPhys.size(); i++) {delete hadronPhys[i];}
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::ConstructParticle()
{
decPhysicsList->ConstructParticle();
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::ConstructProcess()
{
// transportation
@@ -160,20 +105,11 @@ void IORTPhysicsList::ConstructProcess()
emPhysicsList->ConstructProcess();
em_config.AddModels();
// decay physics list
decPhysicsList->ConstructProcess();
// hadronic physics lists
for(size_t i=0; i<hadronPhys.size(); i++) {
hadronPhys[i] -> ConstructProcess();
}
// step limitation (as a full process)
//
AddStepMax();
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::AddPhysicsList(const G4String& name)
{
@@ -182,10 +118,7 @@ void IORTPhysicsList::AddPhysicsList(const G4String& name)
}
if (name == emName) return;
/////////////////////////////////////////////////////////////////////////////
// ELECTROMAGNETIC MODELS
/////////////////////////////////////////////////////////////////////////////
if (name == "standard_opt3") {
if (name == "standard_opt3") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmStandardPhysics_option3();
@@ -193,127 +126,28 @@ void IORTPhysicsList::AddPhysicsList(const G4String& name)
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option3" << G4endl;
} else if (name == "LowE_Livermore") {
} else if (name == "livermore") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmLivermorePhysics();
G4RunManager::GetRunManager()-> PhysicsHasBeenModified();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmLivermorePhysics" << G4endl;
} else if (name == "LowE_Penelope") {
} else if (name == "penelope") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmPenelopePhysics();
G4RunManager::GetRunManager()-> PhysicsHasBeenModified();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmPenelopePhysics" << G4endl;
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmPenelopePhysics" << G4endl;}
/////////////////////////////////////////////////////////////////////////////
// HADRONIC MODELS
/////////////////////////////////////////////////////////////////////////////
} else if (name == "Elastic")
{
if(!helIsRegistered)
{
G4cout << "THE FOLLOWING HADRONIC ELASTIC PHYSICS LIST HAS BEEN ACTIVATED: G4HadronElasticPhysics()" << G4endl;
hadronPhys.push_back( new G4HadronElasticPhysics());
helIsRegistered = true;
}
else G4cout << "AN ELASTIC PHYSICS HAS BEEN ALREADY ACTIVATED!" << G4endl;
}
else if (name == "DElastic")
{
if(!helIsRegistered)
{
hadronPhys.push_back( new G4HadronDElasticPhysics());
helIsRegistered = true;
}
else G4cout << "AN ELASTIC PHYSICS HAS BEEN ALREADY ACTIVATED!" << G4endl;
else if (name == "standard_opt4") {
emName = name;
delete emPhysicsList;
emPhysicsList = new G4EmStandardPhysics_option4();
G4RunManager::GetRunManager() -> PhysicsHasBeenModified();
G4cout << "THE FOLLOWING ELECTROMAGNETIC PHYSICS LIST HAS BEEN ACTIVATED: G4EmStandardPhysics_option4" << G4endl;
}
}
else if (name == "HElastic")
{
if(!helIsRegistered)
{
hadronPhys.push_back( new G4HadronHElasticPhysics());
helIsRegistered = true;
}
else G4cout << "AN ELASTIC PHYSICS HAS BEEN ALREADY ACTIVATED!" << G4endl;
}
else if (name == "Em_extra_physics")
{
hadronPhys.push_back( new G4EmExtraPhysics());
}
else if (name == "Stopping_physics")
{
hadronPhys.push_back( new G4StoppingPhysics());
}
else if (name == "Neutron_tracking_cut")
{
hadronPhys.push_back( new G4NeutronTrackingCut());
}
else if (name == "Hadron_QGSP_BIC")
{
hadronPhys.push_back( new G4HadronPhysicsQGSP_BIC());
// helIsRegistered = true;
}
else if (name == "Hadron_QBBC")
{
hadronPhys.push_back(new G4HadronInelasticQBBC());
//bicIsRegistered = true;
G4cout << "THE FOLLOWING HADRONIC INELASTIC PHYSICS LIST HAS BEEN ACTIVATED: G4HadronInelasticQBBC()" << G4endl;
}
else if (name == "binary")
{
hadronPhys.push_back(new G4HadronInelasticQBBC());
//bicIsRegisted = true;
G4cout << "THE FOLLOWING HADRONIC INELASTIC PHYSICS LIST HAS BEEN ACTIVATED: G4HadronInelasticQBBC()" << G4endl;
}
else if (name == "binary_ion")
{
hadronPhys.push_back(new G4IonBinaryCascadePhysics());
//biciIsRegistered = true;
}
/*
else if (name == "local_ion_ion_inelastic")
{
hadronPhys.push_back(new LocalIonIonInelasticPhysic());
locIonIonInelasticIsRegistered = true;
}
else if (name == "local_incl_ion_ion_inelastic")
{
hadronPhys.push_back(new LocalINCLIonIonInelasticPhysic());
locIonIonInelasticIsRegistered = true;
}
*/
else if (name == "decay")
{
hadronPhys.push_back(new G4DecayPhysics());
//radioactiveDecayIsRegistered = true;
}
else if (name == "radioactive_decay" && !radioactiveDecayIsRegistered )
{
hadronPhys.push_back(new G4RadioactiveDecayPhysics());
radioactiveDecayIsRegistered = true;
// The following is the construction of the QGSP_BIC_EMY Reference physics list
// reconstructed here like a builder: it should be identical to the
// one contained inside the $G4INSTALL/physics_lists/lists folder
}
else if (name == "QGSP_BIC_EMY")
{
AddPhysicsList("emstandard_opt3");
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 G4HadronPhysicsQGSP_BIC());
hadronPhys.push_back( new G4DecayPhysics());
}
else {
G4cout << "PhysicsList::AddPhysicsList: <" << name << ">"
@@ -322,7 +156,6 @@ void IORTPhysicsList::AddPhysicsList(const G4String& name)
}
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::AddStepMax()
{
// Step limitation seen as a process
@@ -341,7 +174,6 @@ void IORTPhysicsList::AddStepMax()
}
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::SetCuts()
{
@@ -361,21 +193,18 @@ void IORTPhysicsList::SetCuts()
if (verboseLevel>0) DumpCutValuesTable();
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::SetCutForGamma(G4double cut)
{
cutForGamma = cut;
SetParticleCuts(cutForGamma, G4Gamma::Gamma());
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::SetCutForElectron(G4double cut)
{
cutForElectron = cut;
SetParticleCuts(cutForElectron, G4Electron::Electron());
}
/////////////////////////////////////////////////////////////////////////////
void IORTPhysicsList::SetCutForPositron(G4double cut)
{
cutForPositron = cut;
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,13 +33,12 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4SystemOfUnits.hh"
#include "IORTPrimaryGeneratorAction.hh"
#include "IORTPrimaryGeneratorMessenger.hh"
@@ -49,9 +48,7 @@
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "Randomize.hh"
#include "IORTAnalysisManager.hh"
IORTPrimaryGeneratorAction::IORTPrimaryGeneratorAction()
{
// Define the messenger
@@ -88,15 +85,9 @@ void IORTPrimaryGeneratorAction::SetDefaultPrimaryParticle()
G4double defaultsigmaEnergy = 100.0 *CLHEP::keV;
sigmaEnergy = defaultsigmaEnergy;
// Write these values into the analysis if needed. Have to be written separately on change.
IORTAnalysisManager::GetInstance()->
setBeamMetaData(meanKineticEnergy, sigmaEnergy);
// Define the parameters of the initial position:
// the y, z coordinates have a gaussian distribution
// the y, z coordinates have a gaussian distribution
G4double defaultX0 = -862.817 *CLHEP::mm;
X0 = defaultX0;
@@ -131,9 +122,6 @@ void IORTPrimaryGeneratorAction::SetDefaultPrimaryParticle()
void IORTPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
// Increment the event counter
IORTAnalysisManager::GetInstance()->startNewEvent();
// ****************************************
// Set the beam angular apread
// and spot size
@@ -226,21 +214,16 @@ while (true) {
void IORTPrimaryGeneratorAction::SetmeanKineticEnergy (G4double val )
{
meanKineticEnergy = val;
// Update the beam-data in the analysis manager
IORTAnalysisManager::GetInstance()->
setBeamMetaData(meanKineticEnergy, sigmaEnergy);
meanKineticEnergy = val;
G4cout << "The mean Kinetic energy of the incident beam has been changed to (MeV):"
<< meanKineticEnergy/MeV << G4endl;
}
void IORTPrimaryGeneratorAction::SetsigmaEnergy (G4double val )
{
sigmaEnergy = val;
// Update the sigmaenergy in the metadata.
IORTAnalysisManager::GetInstance()->
setBeamMetaData(meanKineticEnergy, sigmaEnergy);
sigmaEnergy = val;
G4cout << "The sigma of the kinetic energy of the incident beam has been changed to (MeV):"
<< sigmaEnergy/MeV << G4endl;
}
void IORTPrimaryGeneratorAction::SetXposition (G4double val )
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,57 +33,33 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include "IORTRunAction.hh"
#include "IORTEventAction.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4ios.hh"
#include "IORTDetectorConstruction.hh"
#include "G4SDManager.hh"
#include "G4Timer.hh"
#include "IORTRunAction.hh"
#include "IORTAnalysisManager.hh"
#include "IORTMatrix.hh"
#include "G4SystemOfUnits.hh"
IORTRunAction::IORTRunAction()
{
}
{}
IORTRunAction::~IORTRunAction()
{
}
{ }
void IORTRunAction::BeginOfRunAction(const G4Run* aRun)
{
G4RunManager::GetRunManager()-> SetRandomNumberStore(true);
G4cout << "Run " << aRun -> GetRunID() << " starts ..." << G4endl;
electromagnetic = 0;
hadronic = 0;
}
void IORTRunAction::EndOfRunAction(const G4Run*)
{
//G4cout << " Summary of Run " << aRun -> GetRunID() <<" :"<< G4endl;
//G4cout << "Number of electromagnetic processes of primary particles in the phantom:"
// << electromagnetic << G4endl;
//G4cout << "Number of hadronic processes of primary particles in the phantom:"
// << hadronic << G4endl;
}
void IORTRunAction::AddEMProcess()
{
electromagnetic += 1;
}
void IORTRunAction::AddHadronicProcess()
{
hadronic += 1;
}
{}
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,13 +33,12 @@
// (b) IBFM-CNR , Segrate (Milano), Italy
// (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
// (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
// (e) University of Wallongong, Australia
// (e) University of Wollongong, Australia
//
// *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
//////////////////////////////////////////////////////////////////////////////////////////////
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4SystemOfUnits.hh"
#include "G4SteppingManager.hh"
#include "G4TrackVector.hh"
#include "IORTSteppingAction.hh"
@@ -52,162 +51,17 @@
#include "G4TrackVector.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4UserEventAction.hh" // NOT INCLUDED IN geant4.9.3p01_version
#include "IORTAnalysisManager.hh"
#include "G4UserEventAction.hh"
#include "IORTRunAction.hh"
#include "G4SystemOfUnits.hh"
/////////////////////////////////////////////////////////////////////////////
IORTSteppingAction::IORTSteppingAction( IORTRunAction *run)
{
runAction = run;
}
IORTSteppingAction::IORTSteppingAction( IORTRunAction *)
{}
/////////////////////////////////////////////////////////////////////////////
IORTSteppingAction::~IORTSteppingAction()
{
}
{}
/////////////////////////////////////////////////////////////////////////////
void IORTSteppingAction::UserSteppingAction(const G4Step* aStep)
void IORTSteppingAction::UserSteppingAction(const G4Step*)
{
/*
// USEFULL METHODS TO RETRIEVE INFORMATION DURING THE STEPS
if( (aStep->GetTrack()->GetVolume()->GetName() == "DetectorPhys")
&& aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton")
//G4int evtNb = G4RunManager::GetRunManager()->GetCurrentEvent() -> GetEventID();
{
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;
}
*/
if( aStep->GetTrack()->GetVolume()->GetName() == "NewDetectorPhys"){
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;
IORTAnalysisManager* analysisMgr = IORTAnalysisManager::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
IORTAnalysisManager::GetInstance()->FillFragmentTuple(1, 1.0, energy, posX, posY, posZ);
}
G4String secondaryParticleName = def -> GetParticleName();
//G4cout <<"Particle: " << secondaryParticleName << G4endl;
//G4cout <<"Energy: " << secondaryParticleKineticEnergy << G4endl;
IORTAnalysisManager* analysis = IORTAnalysisManager::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);
}
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")
{
G4String secondaryParticleName = (*fSecondary)[lp1]->GetDefinition() -> GetParticleName();
G4double secondaryParticleKineticEnergy = (*fSecondary)[lp1] -> GetKineticEnergy();
IORTAnalysisManager* analysis = IORTAnalysisManager::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);
}
}
}
}