Geant4  10.02.p01
IORTMatrix.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // This is the *BASIC* version of IORT, a Geant4-based application
27 //
28 // Main Authors: G.Russo(a,b), C.Casarino*(c), G.C. Candiano(c), G.A.P. Cirrone(d), F.Romano(d)
29 // Contributor Authors: S.Guatelli(e)
30 // Past Authors: G.Arnetta(c), S.E.Mazzaglia(d)
31 //
32 // (a) Fondazione Istituto San Raffaele G.Giglio, Cefalù, Italy
33 // (b) IBFM-CNR , Segrate (Milano), Italy
34 // (c) LATO (Laboratorio di Tecnologie Oncologiche), Cefalù, Italy
35 // (d) Laboratori Nazionali del Sud of the INFN, Catania, Italy
36 // (e) University of Wallongong, Australia
37 //
38 // *Corresponding author, email to carlo.casarino@polooncologicocefalu.it
40 
41 #include <fstream>
42 #include <iostream>
43 #include <sstream>
44 #include <iomanip>
45 
46 #include "IORTMatrix.hh"
47 #include "IORTAnalysisManager.hh"
49 
50 #include "globals.hh"
51 #include "G4SystemOfUnits.hh"
52 #include "G4RunManager.hh"
53 #include "G4ParticleGun.hh"
54 
55 // Units definition: CLHEP/Units/SystemOfUnits.h
56 //
59 
60 // Only return a pointer to matrix
62 {
63  return instance;
64 }
65  // This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it
66  // TODO A check on the parameters is required!
68 {
69  if (instance) delete instance;
70  instance = new IORTMatrix(voxelX, voxelY, voxelZ, mass);
71  instance -> Initialize();
72  return instance;
73 }
74 IORTMatrix::IORTMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass):
75  stdFile("Dose.out"),
76  doseUnit(MeV/g)
77 {
78  // Number of the voxels of the phantom
79  // For Y = Z = 1 the phantom is divided in slices (and not in voxels)
80  // orthogonal to the beam axis
81  numberOfVoxelAlongX = voxelX;
82  numberOfVoxelAlongY = voxelY;
83  numberOfVoxelAlongZ = voxelZ;
84  massOfVoxel = mass;
85  // Create the dose matrix
87  if (matrix)
88  {
89  G4cout << "IORTMatrix: Memory space to store physical dose into " <<
91  " voxels has been allocated " << G4endl;
92  }
93  else G4Exception("IORTMatrix::IORTMatrix()", "IORT0005", FatalException, "Error: can't allocate memory to store physical dose!");
94  // Hit voxel (TrackID) marker
95  // This array mark the status of voxel, if a hit occur, with the trackID of the particle
96  // Must be initialized
98  ClearHitTrack();
99 }
100 
103 {
104  delete[] matrix;
105  delete[] hitTrack;
106  // free fluences/dose data memory
107  Clear();
108 }
109 
112 {
113  for (size_t i=0; i<ionStore.size(); i++)
114  {
115  delete[] ionStore[i].dose;
116  delete[] ionStore[i].fluence;
117  }
118  ionStore.clear();
119 }
120 
122 // Initialise the elements of the matrix to zero
124 {
125  // Clear ions store
126  Clear();
127  // Clear dose
129  {
130  matrix[i] = 0;
131  }
132 }
135  // Print generated nuclides list
137 {
138  for (size_t i=0; i<ionStore.size(); i++)
139  {
140  G4cout << ionStore[i].name << G4endl;
141  }
142 }
144  // Clear Hit voxel (TrackID) markers
146 {
148 }
149  // Return Hit status
151 {
152  return &(hitTrack[Index(i,j,k)]);
153 }
155 // Dose methods...
156 // Fill DOSE/fluence matrix for secondary particles:
157 // If fluence parameter is true (default value is FALSE) then fluence at voxel (i, j, k) is increased.
158 // The energyDeposit parameter fill the dose matrix for voxel (i,j,k)
160 
162  G4ParticleDefinition* particleDef,
163  G4int i, G4int j, G4int k,
164  G4double energyDeposit,
165  G4bool fluence)
166 {
167  if ( (energyDeposit <=0. && !fluence) || !secondary) return false;
168  // Get Particle Data Group particle ID
169  G4int PDGencoding = particleDef -> GetPDGEncoding();
170  PDGencoding -= PDGencoding%10;
171 
172  // Search for already allocated data...
173  for (size_t l=0; l < ionStore.size(); l++)
174  {
175  if (ionStore[l].PDGencoding == PDGencoding )
176  { // Is it a primary or a secondary particle?
177  if ( ((trackID == 1) && (ionStore[l].isPrimary)) || ((trackID !=1) && (!ionStore[l].isPrimary)))
178  {
179  if (energyDeposit > 0.) ionStore[l].dose[Index(i, j, k)] += energyDeposit/massOfVoxel;
180 
181  // Fill a matrix per each ion with the fluence
182  if (fluence) ionStore[l].fluence[Index(i, j, k)]++;
183  return true;
184  }
185  }
186  }
187 
188  G4int Z = particleDef-> GetAtomicNumber();
189  G4int A = particleDef-> GetAtomicMass();
190 
191  G4String fullName = particleDef -> GetParticleName();
192  G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy
193  // Let's put a new particle in our store...
194  ion newIon =
195  {
196  (trackID == 1) ? true:false,
197  PDGencoding,
198  name,
199  name.length(),
200  Z,
201  A,
204  };
205  // Initialize data
206  if (newIon.dose && newIon.fluence)
207  {
209  {
210  newIon.dose[q] = 0.;
211  newIon.fluence[q] = 0;
212  }
213  if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit/massOfVoxel;
214  if (fluence) newIon.fluence[Index(i, j, k)]++;
215 
216  ionStore.push_back(newIon);
217 
218  // TODO Put some verbosity check
219  /*
220  G4cout << "Memory space to store the DOSE/FLUENCE into " <<
221  numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ <<
222  " voxels has been allocated for the nuclide " << newIon.name <<
223  " (Z = " << Z << ", A = " << A << ")" << G4endl ;
224  */
225  return true;
226  }
227  else // XXX Out of memory! XXX
228  {
229  return false;
230  }
231 
232 }
233 
236  // Methods to store data to filenames...
239  //
240  // General method to store matrix data to filename
241 void IORTMatrix::StoreMatrix(G4String file, void* data, size_t psize)
242 {
243  if (data)
244  {
245  ofs.open(file, std::ios::out);
246  if (ofs.is_open())
247  {
248  for(G4int i = 0; i < numberOfVoxelAlongX; i++)
249  for(G4int j = 0; j < numberOfVoxelAlongY; j++)
250  for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
251  {
252  G4int n = Index(i, j, k);
253  // Check for data type: u_int, G4double, XXX
254  if (psize == sizeof(unsigned int))
255  {
256  unsigned int* pdata = (unsigned int*)data;
257  if (pdata[n]) ofs << i << '\t' << j << '\t' <<
258  k << '\t' << pdata[n] << G4endl;
259  }
260  else if (psize == sizeof(G4double))
261  {
262  G4double* pdata = (G4double*)data;
263  if (pdata[n]) ofs << i << '\t' << j << '\t' <<
264  k << '\t' << pdata[n] << G4endl;
265  }
266  }
267  ofs.close();
268  }
269  }
270 }
271 
272  // Store fluence per single ion in multiple files
274 {
275  for (size_t i=0; i < ionStore.size(); i++){
276  StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int));
277  }
278 }
279  // Store dose per single ion in multiple files
281 {
282 
283  for (size_t i=0; i < ionStore.size(); i++){
284  StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double));
285  }
286 }
288  // Store dose for all ions into a single file and into ntuples.
289  // Please note that this function is called via messenger commands
290  // defined in the IORTAnalysisFileMessenger.cc class file
292 {
293 #define width 15L
294  filename = (file=="") ? stdFile:file;
295  // Sort like periodic table
296  std::sort(ionStore.begin(), ionStore.end());
297  G4cout << "Dose is being written to " << filename << G4endl;
298  ofs.open(filename, std::ios::out);
299  if (ofs.is_open())
300  {
301  // Write the voxels index and the list of particles/ions
302  ofs << std::setprecision(6) << std::left <<
303  "i\tj\tk\t";
304  // Total dose
305  ofs << std::setw(width) << "Dose(MeV/g)";
306  if (secondary)
307  {
308  for (size_t l=0; l < ionStore.size(); l++)
309  {
310  G4String a = (ionStore[l].isPrimary) ? "_1":""; // is it a primary?
311  ofs << std::setw(width) << ionStore[l].name + a <<
312  std::setw(width) << ionStore[l].name + a;
313  }
314  ofs << G4endl;
315 
316  /*
317  * PDGencondig
318  */
319  /*
320  ofs << std::setprecision(6) << std::left <<
321  "0\t0\t0\t";
322 
323  // Total dose
324  ofs << std::setw(width) << '0';
325  for (size_t l=0; l < ionStore.size(); l++)
326  {
327  ofs << std::setw(width) << ionStore[l].PDGencoding <<
328  std::setw(width) << ionStore[l].PDGencoding;
329  }
330  ofs << G4endl;
331  */
332  }
333  // Write data
334  for(G4int i = 0; i < numberOfVoxelAlongX; i++)
335  for(G4int j = 0; j < numberOfVoxelAlongY; j++)
336  for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
337  {
338  G4int n = Index(i, j, k);
339  // Write only not identically null data lines
340  if (matrix[n])
341  {
342  ofs << G4endl;
343  ofs << i << '\t' << j << '\t' << k << '\t';
344  // Total dose
345  ofs << std::setw(width) << matrix[n]/massOfVoxel/doseUnit;
346  if (secondary)
347  {
348  for (size_t l=0; l < ionStore.size(); l++)
349  {
350  // Fill ASCII file rows
351  ofs << std::setw(width) << ionStore[l].dose[n]/massOfVoxel/doseUnit <<
352  std::setw(width) << ionStore[l].fluence[n];
353  }
354  }
355  }
356  }
357  ofs.close();
358  }
359 }
361 
363 {
365  for(G4int i = 0; i < numberOfVoxelAlongX; i++)
366  for(G4int j = 0; j < numberOfVoxelAlongY; j++)
367  for(G4int k = 0; k < numberOfVoxelAlongZ; k++)
368  {
369  G4int n = Index(i, j, k);
370  for (size_t l=0; l < ionStore.size(); l++)
371 
372  {
373  // Do the same work for .root file: fill dose/fluence ntuple
374  analysis -> FillVoxelFragmentTuple( i, j, k,
375  ionStore[l].A,
376  ionStore[l].Z,
377  ionStore[l].dose[n]/massOfVoxel/doseUnit,
378  ionStore[l].fluence[n] );
379 
380 
381  }
382 
383  }
384 }
385 
387  G4double energyDeposit)
388 {
389  if (matrix)
390  matrix[Index(i,j,k)] += energyDeposit;
391 
392  // Store the energy deposit in the matrix element corresponding
393  // to the phantom voxel
394 }
396 {
397  // Store the information of the matrix in a ntuple and in
398  // a 1D Histogram
399 }
400 
401 
402 
403 
static const double MeV
Definition: G4SIunits.hh:211
void Clear()
Definition: IORTMatrix.cc:111
G4int numberOfVoxelAlongY
Definition: IORTMatrix.hh:134
G4double * dose
G4String name
Definition: TRTMaterials.hh:40
void StoreMatrix(G4String file, void *data, size_t psize)
Definition: IORTMatrix.cc:241
static G4bool secondary
Definition: IORTMatrix.hh:83
G4double a
Definition: TRTMaterials.hh:39
G4int * GetHitTrack(G4int i, G4int j, G4int k)
Definition: IORTMatrix.cc:150
G4double massOfVoxel
Definition: IORTMatrix.hh:136
A class for connecting the simulation to an analysis package.
int G4int
Definition: G4Types.hh:78
G4double doseUnit
Definition: IORTMatrix.hh:146
void TotalEnergyDeposit()
Definition: IORTMatrix.cc:395
G4String stdFile
Definition: IORTMatrix.hh:140
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
G4double * matrix
Definition: IORTMatrix.hh:138
unsigned int * fluence
bool G4bool
Definition: G4Types.hh:79
void StoreDoseData()
Definition: IORTMatrix.cc:280
void StoreFluenceData()
Definition: IORTMatrix.cc:273
G4int numberOfVoxelAlongX
Definition: IORTMatrix.hh:133
void ClearHitTrack()
Definition: IORTMatrix.cc:145
const G4int n
static IORTAnalysisManager * GetInstance()
Get the pointer to the analysis manager.
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool Fill(G4int, G4ParticleDefinition *particleDef, G4int i, G4int j, G4int k, G4double energyDeposit, G4bool fluence=false)
Definition: IORTMatrix.cc:161
static IORTMatrix * instance
Definition: IORTMatrix.hh:132
static const double g
Definition: G4SIunits.hh:180
IORTMatrix(G4int numberOfVoxelAlongX, G4int numberOfVoxelAlongY, G4int numberOfVoxelAlongZ, G4double massOfVoxel)
Definition: IORTMatrix.cc:74
void PrintNuclides()
Definition: IORTMatrix.cc:136
G4int * hitTrack
Definition: IORTMatrix.hh:139
void Initialize()
Definition: IORTMatrix.cc:123
#define G4endl
Definition: G4ios.hh:61
static IORTMatrix * GetInstance()
Definition: IORTMatrix.cc:61
std::vector< ion > ionStore
Definition: IORTMatrix.hh:144
double G4double
Definition: G4Types.hh:76
G4String filename
Definition: IORTMatrix.hh:140
G4int numberOfVoxelAlongZ
Definition: IORTMatrix.hh:135
std::ofstream ofs
Definition: IORTMatrix.hh:141
#define width
void StoreDoseFluenceRoot()
Definition: IORTMatrix.cc:362
void StoreDoseFluenceAscii(G4String filename="")
Definition: IORTMatrix.cc:291
G4int Index(G4int i, G4int j, G4int k)
Definition: IORTMatrix.hh:120