Import Geant4 10.7.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2020-06-26 10:23:25 +02:00
parent c02c370437
commit 67ba86d073
1871 changed files with 174422 additions and 131884 deletions
@@ -56,6 +56,8 @@
#include "G4VSensitiveDetector.hh"
#include "HadrontherapyRunAction.hh"
#include "G4SystemOfUnits.hh"
#include "HadrontherapyRBE.hh"
#include <G4AccumulableManager.hh>
/////////////////////////////////////////////////////////////////////////////
@@ -91,7 +93,7 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
// Get kinetic energy
G4Track * theTrack = aStep -> GetTrack();
G4double kineticEnergy = theTrack->GetKineticEnergy();
G4ParticleDefinition *particleDef = theTrack -> GetDefinition();
//Get particle name
G4String particleName = particleDef -> GetParticleName();
@@ -119,9 +121,7 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
G4VPhysicalVolume* volumePre = touchPreStep->GetVolume();
G4String namePre = volumePre->GetName();
HadrontherapyMatrix* matrix = HadrontherapyMatrix::GetInstance();
HadrontherapyLet* let = HadrontherapyLet::GetInstance();
@@ -219,6 +219,23 @@ G4bool HadrontherapyDetectorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* )
HitsCollection -> insert(detectorHit);
}
}
auto rbe = HadrontherapyRBE::GetInstance();
if (rbe->IsCalculationEnabled())
{
if (!fRBEAccumulable)
{
fRBEAccumulable = dynamic_cast<HadrontherapyRBEAccumulable*>(G4AccumulableManager::Instance()->GetAccumulable("RBE"));
if (!fRBEAccumulable)
{
G4Exception("HadrontherapyDetectorSD::ProcessHits", "NoAccumulable", FatalException, "Accumulable RBE not found.");
}
}
fRBEAccumulable->Accumulate(kineticEnergy / A, energyDeposit, DX, Z, i, j, k);
}
return true;
}
@@ -58,8 +58,8 @@ HadrontherapyAnalysis::~HadrontherapyAnalysis()
/////////////////////////////////////////////////////////////////////////////
HadrontherapyAnalysis* HadrontherapyAnalysis::GetInstance(){
if (instance == 0) instance = new HadrontherapyAnalysis;
if (instance == 0) instance = new HadrontherapyAnalysis;
return instance;
}
@@ -86,8 +86,8 @@ HadrontherapyMatrix* HadrontherapyMatrix::GetInstance(G4int voxelX, G4int voxelY
/////////////////////////////////////////////////////////////////////////////
HadrontherapyMatrix::HadrontherapyMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass):
stdFile("Dose.out"),
doseUnit(gray)
stdFile("Dose.out"),
doseUnit(gray)
{
// Number of the voxels of the phantom
// For Y = Z = 1 the phantom is divided in slices (and not in voxels)
@@ -96,25 +96,24 @@ doseUnit(gray)
numberOfVoxelAlongY = voxelY;
numberOfVoxelAlongZ = voxelZ;
massOfVoxel = mass;
// Create the dose matrix
matrix = new G4double[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
if (matrix)
{
G4cout << "HadrontherapyMatrix: Memory space to store physical dose into " <<
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated " << G4endl;
numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
" voxels has been allocated " << G4endl;
}
else G4Exception("HadrontherapyMatrix::HadrontherapyMatrix()", "Hadrontherapy0005", FatalException, "Can't allocate memory to store physical dose!");
// Hit voxel (TrackID) marker
// This array mark the status of voxel, if a hit occur, with the trackID of the particle
// Must be initialized
hitTrack = new G4int[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ];
ClearHitTrack();
}
@@ -172,15 +171,12 @@ void HadrontherapyMatrix::ClearHitTrack()
for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0;
}
// Return Hit status
G4int* HadrontherapyMatrix::GetHitTrack(G4int i, G4int j, G4int k)
{
return &(hitTrack[Index(i,j,k)]);
}
/////////////////////////////////////////////////////////////////////////////
// Dose methods...
// Fill DOSE/fluence matrix for secondary particles:
@@ -193,41 +189,38 @@ G4bool HadrontherapyMatrix::Fill(G4int trackID,
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;
// 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,
@@ -239,8 +232,8 @@ G4bool HadrontherapyMatrix::Fill(G4int trackID,
new G4double[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ],
new unsigned int[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ]
};
// Initialize data
if (newIon.dose && newIon.fluence)
{
@@ -249,20 +242,19 @@ G4bool HadrontherapyMatrix::Fill(G4int trackID,
newIon.dose[q] = 0.;
newIon.fluence[q] = 0;
}
if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit;
if (fluence) newIon.fluence[Index(i, j, k)]++;
ionStore.push_back(newIon);
return true;
}
else // XXX Out of memory! XXX
{
return false;
}
}
/////////////////////////////////////////////////////////////////////////////
@@ -284,25 +276,23 @@ void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize)
for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
{
G4int n = Index(i, j, k);
if (psize == sizeof(unsigned int))
{
unsigned int* pdata = (unsigned int*)data;
if (pdata[n])
ofs << i << '\t' << j << '\t' << k << '\t' << pdata[n] << G4endl;
}
else if (psize == sizeof(G4double))
{
G4double* pdata = (G4double*)data;
if (pdata[n]) ofs << i << '\t' << j << '\t' << k << '\t' << pdata[n] << G4endl;
}
}
ofs.close();
}
}
@@ -321,88 +311,92 @@ void HadrontherapyMatrix::StoreFluenceData()
// Store dose per single ion in multiple files
void HadrontherapyMatrix::StoreDoseData()
{
for (size_t i=0; i < ionStore.size(); i++){
StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double));
}
}
////////////////////////////////////////////////////////////////////////
// Store dose into a single file
// or in histograms. Please note that this function is called via
// or in histograms. Please, note that this function is called via
// messenger commands
// defined in the HadrontherapyAnalysisFileMessenger.cc class file
void HadrontherapyMatrix::StoreDoseFluenceAscii(G4String file)
{
#define width 15L
filename = (file=="") ? stdFile:file;
// 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";
//ofs << std::setprecision(6) << std::left << "i\tj\tk\t";
ofs << "i" << '\t' << "j" << '\t' << "k";
G4cout << "i" << '\t' << "j" << '\t' << "k";
// Total dose
ofs << std::setw(width) << "Dose(Gy)";
ofs <<'\t' <<"Dose(Gy)";
//ofs << std::setw(width) << "Dose(Gy)";
G4cout << '\t' << "Dose(Gy)";
G4String fluence = "_f";
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;
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 + fluence;
ofs << '\t' << ionStore[l].name + a <<
'\t' << ionStore[l].name + a + fluence;
G4cout << '\t' << ionStore[l].name + a <<
'\t' << ionStore[l].name + a + fluence;
}
ofs << G4endl;
//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);
if (matrix[n])
{
ofs << G4endl;
ofs << i << '\t' << j << '\t' << k << '\t';
// Total dose
ofs << std::setw(width) << (matrix[n]/massOfVoxel)/doseUnit;
//ofs << std::setw(width) << (matrix[n]/massOfVoxel)/doseUnit;
ofs << (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 << std::setw(width) << ionStore[l].dose[n]/massOfVoxel/doseUnit <<
// std::setw(width) << ionStore[l].fluence[n];
ofs << '\t' << ionStore[l].dose[n]/massOfVoxel/doseUnit <<
'\t' << ionStore[l].fluence[n];
}
}
}
}
ofs.close();
}
}
//////////////////////////////////////////////////////////////////////////////
void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k,
@@ -410,9 +404,9 @@ void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k,
{
if (matrix)
matrix[Index(i,j,k)] += energyDeposit;
// Store the energy deposit in the matrix element corresponding
// to the phantom voxel
// Store the energy deposit in the matrix element corresponding
// to the phantom voxel
}
@@ -50,48 +50,17 @@ HadrontherapyRunAction::HadrontherapyRunAction()
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->RegisterAccumulable(&fRBEAccumulable);
// Create analysis manager
// The choice of analysis technology is done via selectin of a namespace
// in Analysis.hh
auto analysisManager =G4AnalysisManager::Instance();
G4cout << "Using " << analysisManager -> GetType() << G4endl;
analysisManager->SetVerboseLevel(1);
analysisManager->SetFirstHistoId(1);
// Comment out the following line to generate an N-tuple
analysisManager-> SetFirstNtupleId(2);
// Creating the histograms of primary kinetic
// energy (Ekin) and of the energy deposited (Edep)
// in the first voxel/slice of the water phantom
analysisManager -> CreateH1("Ekin","Ekin the voxel", 400,20*MeV, 60*MeV);
analysisManager -> CreateH1("Edep","Edep the voxel", 200, -10, 10*MeV);
// Example of how to create an Ntuple (comment-out, if needed)
//analysisManager->CreateNtuple("NYUPLA", "Edep and TrackL");
//analysisManager->CreateNtupleDColumn("Ekin");
}
/////////////////////////////////////////////////////////////////////////////
HadrontherapyRunAction::~HadrontherapyRunAction()
{
delete G4AnalysisManager::Instance();
//delete G4AnalysisManager::Instance();
}
/////////////////////////////////////////////////////////////////////////////
void HadrontherapyRunAction::BeginOfRunAction(const G4Run* aRun)
{
// Get analysis manager
auto analysisManager = G4AnalysisManager::Instance();
// Open an output file
//
G4String fileName = "Hadrontherapy";
analysisManager->OpenFile(fileName);
{
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Reset();
@@ -112,12 +81,7 @@ void HadrontherapyRunAction::BeginOfRunAction(const G4Run* aRun)
void HadrontherapyRunAction::EndOfRunAction(const G4Run*)
{
auto analysisManager = G4AnalysisManager::Instance();
//G4cout << " Summary of Run " << aRun -> GetRunID() <<" :"<< G4endl;
//G4cout << "Number of electromagnetic processes of primary particles in the phantom:"
// << electromagnetic << G4endl;
//G4cout << "Number of hadronic processes of primary particles in the phantom:"
// << hadronic << G4endl;
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Merge();