ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ML2ExpVoxels.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ML2ExpVoxels.cc
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 // The code was written by :
27 // ^Claudio Andenna claudio.andenna@ispesl.it, claudio.andenna@iss.infn.it
28 // *Barbara Caccia barbara.caccia@iss.it
29 // with the support of Pablo Cirrone (LNS, INFN Catania Italy)
30 // with the contribute of Alessandro Occhigrossi*
31 //
32 // ^INAIL DIPIA - ex ISPESL and INFN Roma, gruppo collegato Sanità, Italy
33 // *Istituto Superiore di Sanità and INFN Roma, gruppo collegato Sanità, Italy
34 // Viale Regina Elena 299, 00161 Roma (Italy)
35 // tel (39) 06 49902246
36 // fax (39) 06 49387075
37 //
38 // more information:
39 // http://g4advancedexamples.lngs.infn.it/Examples/medical-linac
40 //
41 //*******************************************************//
42 
43 #include <fstream>
44 
45 #include "ML2ExpVoxels.hh"
46 #include "G4SystemOfUnits.hh"
47 
49  G4String FileExperimentalData, G4String FileExperimentalDataOut):startCurve(0),
50  stopCurve(0),chi2Factor(0)
51 {
52  char a[10];
53  sprintf(a,"%d", seed);
54  seedName = (G4String)a;
56  nRecycling = 1;
57 
58 
59  fullFileOut = FileExperimentalDataOut+seedName+".m";
60  fullFileIn = FileExperimentalData;
61  nParticle = nTotalEvents = 0;
62 
63 // define the extremes of global-volume containing all experimental voxels
64  G4double extr = 100000000000.;
65  minZone.set(extr, extr, extr);
66  maxZone.set(-extr, -extr, -extr);
67  bHasExperimentalData = bData;
68 }
69 
71 {
72  delete [] startCurve;
73  delete [] stopCurve;
74  delete [] chi2Factor;
75  delete [] nVoxelsgeometry;
76 }
78 {
79  bHasExperimentalData = true;
80  std::ifstream in;
81 
82  Svoxel voxel;
83  voxel.volumeId = 0;
84  G4ThreeVector pos, halfSize;
86 
87  in.open(fullFileIn, std::ios::in);
88  if (in)
89  {
90  G4String appo;
91  char a[1000];
92  in.getline(a,1000,'\n');
93  headerText1 = (G4String)a;
94  in.getline(a,1000,'\n');
95  in >> nCurves;
96  startCurve = new G4int[nCurves];
97  stopCurve = new G4int[nCurves];
99  for (int i = 0; i < nCurves; i++)
100  {
101  chi2Factor[i] = 0.;
102  in >> startCurve[i];
103  in >> stopCurve[i];
104  in >> chi2Factor[i];
105  }
106  in.getline(a,1000,'\n');
107  in.getline(a,1000,'\n');
108  headerText2 = (G4String)a;
109  std::string line;
110 
111  while ( !in.eof() )
112  {
113  in >> pos;
114  in >> halfSize;
115 
117  {
118  in >> expDose;
119  voxel.expDose = expDose/100.*(joule/kg); // input data in cGy
120  }
121  else
122  {
123  voxel.expDose = 0.;
124  }
125  voxel.pos=pos;
126  voxel.halfSize = halfSize;
127  voxel.depEnergy = 0.;
128  voxel.depEnergy2 = 0.;
129  voxel.nEvents = 0;
130  voxel.depEnergyNorm = 0.;
131  voxel.depEnergyNormError = 0.;
132  vec_voxels.push_back(voxel);
133 
134  // calculate the actual extremes of the global-volume containing all the experimental data
135  if ( minZone.getX()>pos.getX()-halfSize.getX() )
136  { minZone.setX(pos.getX()-halfSize.getX()); }
137  if ( maxZone.getX()<pos.getX()+halfSize.getX() )
138  { maxZone.setX(pos.getX()+halfSize.getX()); }
139 
140  if ( minZone.getY()>pos.getY()-halfSize.getY() )
141  { minZone.setY(pos.getY()-halfSize.getY()); }
142  if ( maxZone.getY()<pos.getY()+halfSize.getY() )
143  { maxZone.setY(pos.getY()+halfSize.getY()); }
144 
145  if ( minZone.getZ()>pos.getZ()-halfSize.getZ() )
146  { minZone.setZ(pos.getZ()-halfSize.getZ()); }
147  if ( maxZone.getZ()<pos.getZ()+halfSize.getZ() )
148  { maxZone.setZ(pos.getZ()+halfSize.getZ()); }
149  }
150  }
151  else
152  {
153  G4cout << "ERROR I can't find the experimental data file" << G4endl;
154  return false;
155  }
156  in.close();
157 
158  nVoxelsgeometry = new G4int[(G4int) vec_voxels.size()];
160 
161  return true;
162 }
164 {
165  for (int i=0; i<(int) vec_voxels.size(); i++ )
166  {nVoxelsgeometry[i] = 0;}
167 }
168 
169 void CML2ExpVoxels::add(const G4Step* aStep)
170 {
172  G4double depEnergy, density, voxelVolume;
173 
174  pos = aStep->GetPreStepPoint()->GetPosition();
175  depEnergy = aStep->GetTotalEnergyDeposit();
177 
178  G4ThreeVector minPos, maxPos;
179  G4bool newEvent=false;
180  G4double voxelMass, dose;
181 
182  // check if the event is inside the global-volume
183  if (minZone.getX() <= pos.getX() && pos.getX() < maxZone.getX() &&
184  minZone.getY() <= pos.getY() && pos.getY() < maxZone.getY() &&
185  minZone.getZ() <= pos.getZ() && pos.getZ() < maxZone.getZ())
186  {
187  // look for the voxel containing the event
188  for (int i = 0; i < (int)vec_voxels.size(); i++)
189  {
190  minPos = vec_voxels[i].pos-vec_voxels[i].halfSize;
191  maxPos = vec_voxels[i].pos+vec_voxels[i].halfSize;
192  if ( minPos.getX() <= pos.getX() && pos.getX() < maxPos.getX() &&
193  minPos.getY() <= pos.getY() && pos.getY() < maxPos.getY() &&
194  minPos.getZ() <= pos.getZ() && pos.getZ() < maxPos.getZ() )
195  {
196  voxelVolume = vec_voxels[i].halfSize.getX()*vec_voxels[i].halfSize.getY()*vec_voxels[i].halfSize.getZ()*8.;
197  voxelMass = density*voxelVolume;
198  // calculate the dose
199  dose=depEnergy/(voxelMass*nRecycling);
200  vec_voxels[i].nEvents++;
201  nVoxelsgeometry[i]++;
202  vec_voxels[i].depEnergy += dose;
203  vec_voxels[i].depEnergy2 += dose*dose;
204  newEvent = true;
205 
207  particle -> dir = aStep -> GetPreStepPoint() -> GetMomentumDirection();
208  particle -> pos = aStep -> GetPreStepPoint() -> GetPosition();
209  particle -> kinEnergy = dose; // I use the same kinEnergy name to store the dose
210  particle -> nPrimaryPart = -1;
211  particle -> partPDGE = aStep -> GetTrack() -> GetDefinition() -> GetPDGEncoding();
212  particle -> primaryParticlePDGE = -1;
213  particle -> volumeId = i; // voxel index where the dose is accumulating
214  particle -> volumeName = "-1";
215  }
216  }
217  if ( newEvent )
218  {
219  // save data
220  nTotalEvents++;
222  {
223  saveResults();
224  }
225  }
226  }
227 }
228 
230 {
231  int n = vec_voxels[0].nEvents;
232  for (int i = 0; i < (int)vec_voxels.size(); i++)
233  {
234  if ( n > vec_voxels[i].nEvents )
235  { n = vec_voxels[i].nEvents; }
236  }
237  return n;
238 }
240 {
241  int n = nVoxelsgeometry[0];
242  for ( int i = 0; i < (int)vec_voxels.size(); i++)
243  {
244  if ( n < nVoxelsgeometry[i] )
245  { n = nVoxelsgeometry[i]; }
246  }
247  return n;
248 }
250 {
251  std::ofstream out;
252  out.open(fullFileOut, std::ios::out);
253  out << "% " << headerText1 << G4endl;
254  out << "n" << seedName << "=" << nCurves << ";" << G4endl;
255  out << "fh" << seedName << "=[" << G4endl;
256  for (int i = 0; i< nCurves; i++)
257  {
258  out << startCurve[i] << '\t';
259  out << stopCurve[i] << '\t';
260  out << chi2Factor[i] << G4endl;
261  }
262  out << "];" << G4endl;
263  out << "% x [mm], y [mm], z [mm], Dx [mm], Dy [mm], Dz [mm], expDose [Gy], Calculated dose [Gy], Calculated dose2 [Gy^2], nEvents, normDose [Gy], normDoseError [Gy]";
264  out << G4endl;
265  out.close();
266 }
267 
269 {
270  if (nTotalEvents > 0)
271  {
273  saveHeader();
274  std::ofstream out;
275  out.open(fullFileOut, std::ios::app);
276  out << "d" << seedName << "=[" << G4endl;
277  for (int i=0; i<(int)vec_voxels.size(); i++)
278  {
279  out << vec_voxels[i].pos.getX()/mm << '\t' << vec_voxels[i].pos.getY()/mm << '\t' << vec_voxels[i].pos.getZ()/mm << '\t';
280  out << vec_voxels[i].halfSize.getX()/mm << '\t' << vec_voxels[i].halfSize.getY()/mm << '\t' << vec_voxels[i].halfSize.getZ()/mm << '\t';
281  out << vec_voxels[i].expDose/(joule/kg) << '\t' << vec_voxels[i].depEnergy/(joule/kg) << '\t' << vec_voxels[i].depEnergy2/((joule/kg)*(joule/kg)) << '\t' << vec_voxels[i].nEvents << '\t';
282  out << vec_voxels[i].depEnergyNorm/(joule/kg) << '\t' << vec_voxels[i].depEnergyNormError/(joule/kg);
283  out << G4endl;
284  }
285  out << "];" << G4endl;
286  out.close();
287  }
288 }
289 
290 void CML2ExpVoxels::calculateNormalizedEd(std::vector <Svoxel> &vox)
291 {
292  int i,j;
293  G4double cs, cc;
294  int n;
295  G4double d2, dd;
296  G4double v;
297  for (j = 0; j < nCurves; j++)
298  {
299  cs = cc = 0.;
300  for (i = startCurve[j]-1;i<stopCurve[j];i++)
301  {
302  cs += vox[i].depEnergy*vox[i].expDose;
303  cc += vox[i].depEnergy*vox[i].depEnergy;
304  }
305  if (cc>0.)
306  {
307  chi2Factor[j] = cs/cc;
308  }
309  for (i = startCurve[j]-1; i < stopCurve[j]; i++)
310  {
311  dd = vox[i].depEnergy*vox[i].depEnergy;
312  d2 = vox[i].depEnergy2;
313  n = vox[i].nEvents;
314  vox[i].depEnergyNorm = chi2Factor[j]*vox[i].depEnergy;
315  v = n*d2-dd;
316  if (v < 0.) { v=0; }
317  if (n > 1) { vox[i].depEnergyNormError = chi2Factor[j]*std::sqrt(v/(n-1)); }
318  if (n == 1) { vox[i].depEnergyNormError = vox[i].depEnergyNorm; }
319  }
320  }
321 }