Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Hadrontherapy advanced example for Geant4 << 26 // This is the *BASIC* version of Hadrontherapy, a Geant4-based application 27 // See more at: https://twiki.cern.ch/twiki/bi << 27 // See more at: http://g4advancedexamples.lngs.infn.it/Examples/hadrontherapy >> 28 // >> 29 // Visit the Hadrontherapy web site (http://www.lns.infn.it/link/Hadrontherapy) to request >> 30 // the *COMPLETE* version of this program, together with its documentation; >> 31 // Hadrontherapy (both basic and full version) are supported by the Italian INFN >> 32 // Institute in the framework of the MC-INFN Group >> 33 // >> 34 >> 35 #include "HadrontherapyMatrix.hh" >> 36 #include "HadrontherapyAnalysisManager.hh" >> 37 #include "G4RunManager.hh" >> 38 #include "HadrontherapyPrimaryGeneratorAction.hh" >> 39 #include "G4ParticleGun.hh" 28 40 29 #include <fstream> 41 #include <fstream> >> 42 #include <unistd.h> 30 #include <iostream> 43 #include <iostream> 31 #include <sstream> 44 #include <sstream> 32 #include <iomanip> 45 #include <iomanip> 33 << 34 #include "HadrontherapyMatrix.hh" << 35 #include "HadrontherapyPrimaryGeneratorAction. << 36 #include "globals.hh" 46 #include "globals.hh" 37 #include "G4SystemOfUnits.hh" << 38 #include "G4RunManager.hh" << 39 #include "G4ParticleGun.hh" << 40 #include "HadrontherapySteppingAction.hh" << 41 #include "HadrontherapyAnalysisFileMessenger.h << 42 #include "G4SystemOfUnits.hh" << 43 #include <time.h> << 44 << 45 HadrontherapyAnalysis* HadrontherapyAnalysis:: << 46 ////////////////////////////////////////////// << 47 << 48 HadrontherapyAnalysis::HadrontherapyAnalysis() << 49 { << 50 fMess = new HadrontherapyAnalysisFileMesse << 51 } << 52 << 53 ////////////////////////////////////////////// << 54 HadrontherapyAnalysis::~HadrontherapyAnalysis( << 55 { << 56 delete fMess; << 57 } << 58 << 59 ////////////////////////////////////////////// << 60 HadrontherapyAnalysis* HadrontherapyAnalysis:: << 61 << 62 if (instance == 0) instance = new Hadronth << 63 return instance; << 64 } << 65 47 >> 48 // Units definition: CLHEP/Units/SystemOfUnits.h >> 49 // 66 HadrontherapyMatrix* HadrontherapyMatrix::inst 50 HadrontherapyMatrix* HadrontherapyMatrix::instance = NULL; 67 G4bool HadrontherapyMatrix::secondary = false; 51 G4bool HadrontherapyMatrix::secondary = false; 68 52 69 << 70 // Only return a pointer to matrix 53 // Only return a pointer to matrix 71 HadrontherapyMatrix* HadrontherapyMatrix::GetI << 54 HadrontherapyMatrix* HadrontherapyMatrix::GetInstance() 72 { 55 { 73 return instance; << 56 return instance; 74 } 57 } 75 << 58 // This STATIC method delete (!) the old matrix and rewrite a new object returning a pointer to it 76 ////////////////////////////////////////////// << 59 // TODO A check on the parameters is required! 77 // This STATIC method delete (!) the old matri << 60 HadrontherapyMatrix* HadrontherapyMatrix::GetInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass) 78 // TODO A check on the parameters is required! << 61 { 79 HadrontherapyMatrix* HadrontherapyMatrix::GetI << 62 if (instance) delete instance; 80 { << 63 instance = new HadrontherapyMatrix(voxelX, voxelY, voxelZ, mass); 81 if (instance) delete instance; << 64 instance -> Initialize(); 82 instance = new HadrontherapyMatrix(voxelX, << 65 return instance; 83 instance -> Initialize(); << 84 return instance; << 85 } 66 } 86 << 87 ////////////////////////////////////////////// << 88 HadrontherapyMatrix::HadrontherapyMatrix(G4int 67 HadrontherapyMatrix::HadrontherapyMatrix(G4int voxelX, G4int voxelY, G4int voxelZ, G4double mass): 89 stdFile("Dose.out"), 68 stdFile("Dose.out"), 90 doseUnit(gray) << 69 doseUnit(MeV/g) 91 { << 70 { 92 // Number of the voxels of the phantom << 71 // Number of the voxels of the phantom 93 // For Y = Z = 1 the phantom is divided in << 72 // For Y = Z = 1 the phantom is divided in slices (and not in voxels) 94 // orthogonal to the beam axis << 73 // orthogonal to the beam axis 95 numberOfVoxelAlongX = voxelX; << 74 numberOfVoxelAlongX = voxelX; 96 numberOfVoxelAlongY = voxelY; << 75 numberOfVoxelAlongY = voxelY; 97 numberOfVoxelAlongZ = voxelZ; << 76 numberOfVoxelAlongZ = voxelZ; 98 massOfVoxel = mass; << 77 massOfVoxel = mass; 99 << 78 // Create the dose matrix 100 << 79 matrix = new G4double[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ]; 101 // Create the dose matrix << 80 if (matrix) 102 matrix = new G4double[numberOfVoxelAlongX* << 81 { 103 if (matrix) << 82 G4cout << "HadrontherapyMatrix: Memory space to store physical dose into " << 104 { << 83 numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ << 105 G4cout << "HadrontherapyMatrix: Memory << 84 " voxels has been allocated " << G4endl; 106 numberOfVoxelAlongX*numberOf << 85 } 107 " voxels has been allocated << 86 else G4Exception(" HadrontherapyMatrix::HadrontherapyMatrix. Can't allocate memory to store physical dose!"); 108 } << 87 // Hit voxel (TrackID) marker 109 << 88 // This array mark the status of voxel, if a hit occur, with the trackID of the particle 110 else G4Exception("HadrontherapyMatrix::Had << 89 // Must be initialized 111 << 90 hitTrack = new G4int[numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ]; 112 << 91 ClearHitTrack(); 113 // Hit voxel (TrackID) marker << 114 // This array mark the status of voxel, if << 115 // Must be initialized << 116 << 117 hitTrack = new G4int[numberOfVoxelAlongX*n << 118 ClearHitTrack(); << 119 } 92 } 120 93 121 ////////////////////////////////////////////// 94 ///////////////////////////////////////////////////////////////////////////// 122 HadrontherapyMatrix::~HadrontherapyMatrix() 95 HadrontherapyMatrix::~HadrontherapyMatrix() 123 { 96 { 124 delete[] matrix; 97 delete[] matrix; 125 delete[] hitTrack; 98 delete[] hitTrack; >> 99 // free fluences/dose data memory 126 Clear(); 100 Clear(); 127 } 101 } 128 102 129 ////////////////////////////////////////////// 103 ///////////////////////////////////////////////////////////////////////////// 130 void HadrontherapyMatrix::Clear() 104 void HadrontherapyMatrix::Clear() 131 { 105 { 132 for (size_t i=0; i<ionStore.size(); i++) 106 for (size_t i=0; i<ionStore.size(); i++) 133 { 107 { 134 delete[] ionStore[i].dose; << 108 delete[] ionStore[i].dose; 135 delete[] ionStore[i].fluence; << 109 delete[] ionStore[i].fluence; 136 } 110 } 137 ionStore.clear(); 111 ionStore.clear(); 138 } 112 } 139 113 140 ////////////////////////////////////////////// 114 ///////////////////////////////////////////////////////////////////////////// 141 // Initialise the elements of the matrix to ze 115 // Initialise the elements of the matrix to zero 142 << 143 void HadrontherapyMatrix::Initialize() 116 void HadrontherapyMatrix::Initialize() 144 { << 117 { 145 // Clear ions store 118 // Clear ions store 146 Clear(); 119 Clear(); 147 // Clear dose 120 // Clear dose 148 for(int i=0;i<numberOfVoxelAlongX*numberOf 121 for(int i=0;i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ;i++) 149 { 122 { 150 matrix[i] = 0; << 123 matrix[i] = 0; 151 } 124 } 152 } 125 } 153 << 126 ///////////////////////////////////////////////////////////////////////////// 154 ////////////////////////////////////////////// << 127 ///////////////////////////////////////////////////////////////////////////// 155 // Print generated nuclides list << 128 // Print generated nuclides list 156 << 157 ////////////////////////////////////////////// << 158 void HadrontherapyMatrix::PrintNuclides() 129 void HadrontherapyMatrix::PrintNuclides() 159 { 130 { 160 for (size_t i=0; i<ionStore.size(); i++) 131 for (size_t i=0; i<ionStore.size(); i++) 161 { 132 { 162 G4cout << ionStore[i].name << G4endl; << 133 G4cout << ionStore[i].name << G4endl; 163 } 134 } 164 } 135 } 165 << 136 ///////////////////////////////////////////////////////////////////////////// 166 ////////////////////////////////////////////// << 137 // Clear Hit voxel (TrackID) markers 167 // Clear Hit voxel (TrackID) markers << 168 << 169 void HadrontherapyMatrix::ClearHitTrack() 138 void HadrontherapyMatrix::ClearHitTrack() 170 { 139 { 171 for(G4int i=0; i<numberOfVoxelAlongX*numbe << 140 for(G4int i=0; i<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; i++) hitTrack[i] = 0; 172 } 141 } 173 << 142 // Return Hit status 174 // Return Hit status << 175 G4int* HadrontherapyMatrix::GetHitTrack(G4int 143 G4int* HadrontherapyMatrix::GetHitTrack(G4int i, G4int j, G4int k) 176 { 144 { 177 return &(hitTrack[Index(i,j,k)]); << 145 return &(hitTrack[Index(i,j,k)]); 178 } 146 } 179 << 180 ////////////////////////////////////////////// 147 ///////////////////////////////////////////////////////////////////////////// 181 // Dose methods... 148 // Dose methods... 182 // Fill DOSE/fluence matrix for secondary part << 149 // Fill DOSE/fluence matrix for secondary particles: 183 // If fluence parameter is true (default value << 150 // If fluence parameter is true (default value is FALSE) then fluence at voxel (i, j, k) is increased. 184 // The energyDeposit parameter fill the dose m << 151 // The energyDeposit parameter fill the dose matrix for voxel (i,j,k) 185 ////////////////////////////////////////////// 152 ///////////////////////////////////////////////////////////////////////////// >> 153 186 G4bool HadrontherapyMatrix::Fill(G4int trackID 154 G4bool HadrontherapyMatrix::Fill(G4int trackID, 187 G4ParticleDef << 155 G4ParticleDefinition* particleDef, 188 G4int i, G4in << 156 G4int i, G4int j, G4int k, 189 G4double ener << 157 G4double energyDeposit, 190 G4bool fluenc << 158 G4bool fluence) 191 { 159 { 192 << 193 if ( (energyDeposit <=0. && !fluence) || ! 160 if ( (energyDeposit <=0. && !fluence) || !secondary) return false; 194 << 161 // Get Particle Data Group particle ID 195 // Get Particle Data Group particle ID << 196 G4int PDGencoding = particleDef -> GetPDGE 162 G4int PDGencoding = particleDef -> GetPDGEncoding(); 197 PDGencoding -= PDGencoding%10; 163 PDGencoding -= PDGencoding%10; 198 << 164 199 // Search for already allocated data... 165 // Search for already allocated data... 200 for (size_t l=0; l < ionStore.size(); l++) 166 for (size_t l=0; l < ionStore.size(); l++) 201 { 167 { 202 if (ionStore[l].PDGencoding == PDGenco << 168 if (ionStore[l].PDGencoding == PDGencoding ) 203 { // Is it a primary or a secondary << 169 { // Is it a primary or a secondary particle? 204 << 170 if ( trackID ==1 && ionStore[l].isPrimary || trackID !=1 && !ionStore[l].isPrimary) 205 if ( (trackID ==1 && ionStore[l].i << 171 { 206 { << 172 if (energyDeposit > 0.) ionStore[l].dose[Index(i, j, k)] += energyDeposit/massOfVoxel; 207 if (energyDeposit > 0.) << 173 208 << 174 // Fill a matrix per each ion with the fluence 209 ionStore[l].dose[Index(i, << 175 if (fluence) ionStore[l].fluence[Index(i, j, k)]++; 210 << 176 return true; 211 // Fill a matrix per each ion << 177 } 212 << 178 } 213 if (fluence) ionStore[l].fluen << 214 return true; << 215 } << 216 } << 217 } 179 } >> 180 218 G4int Z = particleDef-> GetAtomicNumber(); 181 G4int Z = particleDef-> GetAtomicNumber(); 219 G4int A = particleDef-> GetAtomicMass(); 182 G4int A = particleDef-> GetAtomicMass(); 220 G4String fullName = particleDef -> GetPart << 221 G4String name = fullName.substr (0, fullNa << 222 183 223 // Let's put a new particle in our store.. << 184 G4String fullName = particleDef -> GetParticleName(); 224 ion newIon = << 185 G4String name = fullName.substr (0, fullName.find("[") ); // cut excitation energy >> 186 // Let's put a new particle in our store... >> 187 ion newIon = 225 { 188 { 226 (trackID == 1) ? true:false, << 189 (trackID == 1) ? true:false, 227 PDGencoding, << 190 PDGencoding, 228 name, << 191 name, 229 name.length(), << 192 name.length(), 230 Z, << 193 Z, 231 A, << 194 A, 232 new G4double[numberOfVoxelAlongX * num << 195 new G4double[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ], 233 new unsigned int[numberOfVoxelAlongX * << 196 new unsigned int[numberOfVoxelAlongX * numberOfVoxelAlongY * numberOfVoxelAlongZ] 234 }; << 197 }; 235 << 198 // Initialize data 236 << 237 // Initialize data << 238 if (newIon.dose && newIon.fluence) 199 if (newIon.dose && newIon.fluence) 239 { 200 { 240 for(G4int q=0; q<numberOfVoxelAlongX*n << 201 for(G4int m=0; m<numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ; m++) 241 { << 202 { 242 newIon.dose[q] = 0.; << 203 newIon.dose[m] = 0.; 243 newIon.fluence[q] = 0; << 204 newIon.fluence[m] = 0; 244 } << 205 } 245 << 206 if (energyDeposit > 0.) newIon.dose[Index(i, j, k)] += energyDeposit/massOfVoxel; 246 if (energyDeposit > 0.) newIon.dose[In << 207 if (fluence) newIon.fluence[Index(i, j, k)]++; 247 if (fluence) newIon.fluence[Index(i, j << 208 248 << 209 ionStore.push_back(newIon); 249 ionStore.push_back(newIon); << 210 250 return true; << 211 // TODO Put some verbosity check >> 212 /* >> 213 G4cout << "Memory space to store the DOSE/FLUENCE into " << >> 214 numberOfVoxelAlongX*numberOfVoxelAlongY*numberOfVoxelAlongZ << >> 215 " voxels has been allocated for the nuclide " << newIon.name << >> 216 " (Z = " << Z << ", A = " << A << ")" << G4endl ; >> 217 */ >> 218 return true; 251 } 219 } 252 << 253 else // XXX Out of memory! XXX 220 else // XXX Out of memory! XXX 254 << 255 { 221 { 256 return false; << 222 return false; 257 } 223 } >> 224 258 } 225 } 259 << 226 260 ////////////////////////////////////////////// << 227 ///////////////////////////////////////////////////////////////////////////// 261 ////////////////////////////////////////////// << 228 ///////////////////////////////////////////////////////////////////////////// 262 // Methods to store data to filenames... << 229 // Methods to store data to filenames... 263 ////////////////////////////////////////////// << 230 //////////////////////////////////////////////////////////////////////////// 264 ////////////////////////////////////////////// << 231 //////////////////////////////////////////////////////////////////////////// 265 // << 232 // 266 // General method to store matrix data to file << 233 // General method to store matrix data to filename 267 void HadrontherapyMatrix::StoreMatrix(G4String 234 void HadrontherapyMatrix::StoreMatrix(G4String file, void* data, size_t psize) 268 { 235 { 269 if (data) 236 if (data) 270 { 237 { 271 ofs.open(file, std::ios::out); << 238 ofs.open(file, std::ios::out); 272 if (ofs.is_open()) << 239 if (ofs.is_open()) 273 { << 240 { 274 for(G4int i = 0; i < numberOfVoxel << 241 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 275 for(G4int j = 0; j < numberOfV << 242 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 276 for(G4int k = 0; k < numbe << 243 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 277 { << 244 { 278 G4int n = Index(i, j, << 245 G4int n = Index(i, j, k); 279 << 246 // Check for data type: u_int, G4double, XXX 280 if (psize == sizeof(un << 247 if (psize == sizeof(unsigned int)) 281 { << 248 { 282 unsigned int* pdat << 249 unsigned int* pdata = (unsigned int*)data; 283 << 250 if (pdata[n]) ofs << i << '\t' << j << '\t' << 284 if (pdata[n]) << 251 k << '\t' << pdata[n] << G4endl; 285 << 252 } 286 ofs << i << '\ << 253 else if (psize == sizeof(G4double)) 287 } << 254 { 288 << 255 G4double* pdata = (G4double*)data; 289 else if (psize == size << 256 if (pdata[n]) ofs << i << '\t' << j << '\t' << 290 << 257 k << '\t' << pdata[n] << G4endl; 291 { << 258 } 292 G4double* pdata = << 259 } 293 if (pdata[n]) ofs << 260 ofs.close(); 294 } << 261 } 295 } << 296 ofs.close(); << 297 } << 298 } 262 } 299 } 263 } 300 264 301 ////////////////////////////////////////////// << 265 // Store fluence per single ion in multiple files 302 // Store fluence per single ion in multiple fi << 303 void HadrontherapyMatrix::StoreFluenceData() 266 void HadrontherapyMatrix::StoreFluenceData() 304 { 267 { 305 for (size_t i=0; i < ionStore.size(); i++) 268 for (size_t i=0; i < ionStore.size(); i++){ 306 StoreMatrix(ionStore[i].name + "_Fluen << 269 StoreMatrix(ionStore[i].name + "_Fluence.out", ionStore[i].fluence, sizeof(unsigned int)); 307 } 270 } 308 } 271 } 309 << 272 // Store dose per single ion in multiple files 310 ////////////////////////////////////////////// << 311 // Store dose per single ion in multiple files << 312 void HadrontherapyMatrix::StoreDoseData() 273 void HadrontherapyMatrix::StoreDoseData() 313 { 274 { 314 << 275 315 for (size_t i=0; i < ionStore.size(); i++) 276 for (size_t i=0; i < ionStore.size(); i++){ 316 StoreMatrix(ionStore[i].name + "_Dose. << 277 StoreMatrix(ionStore[i].name + "_Dose.out", ionStore[i].dose, sizeof(G4double)); 317 } 278 } 318 } 279 } 319 << 280 ///////////////////////////////////////////////////////////////////////// 320 ////////////////////////////////////////////// << 281 // Store dose for all ions into a single file and into ntuples. 321 // Store dose into a single file << 282 // Please note that this function is called via messenger commands 322 // or in histograms. Please, note that this fu << 283 // defined in the HadrontherapyAnalysisFileMessenger.cc class file 323 // messenger commands << 324 // defined in the HadrontherapyAnalysisFileMes << 325 void HadrontherapyMatrix::StoreDoseFluenceAsci 284 void HadrontherapyMatrix::StoreDoseFluenceAscii(G4String file) 326 { 285 { 327 #define width 15L 286 #define width 15L 328 filename = (file=="") ? stdFile:file; 287 filename = (file=="") ? stdFile:file; 329 << 330 // Sort like periodic table 288 // Sort like periodic table 331 << 332 std::sort(ionStore.begin(), ionStore.end() 289 std::sort(ionStore.begin(), ionStore.end()); 333 G4cout << "Dose is being written to " << f 290 G4cout << "Dose is being written to " << filename << G4endl; 334 ofs.open(filename, std::ios::out); 291 ofs.open(filename, std::ios::out); 335 << 336 if (ofs.is_open()) 292 if (ofs.is_open()) 337 { 293 { 338 // Write the voxels index and the list << 294 // Write the voxels index and the list of particles/ions 339 //ofs << std::setprecision(6) << std:: << 295 ofs << std::setprecision(6) << std::left << 340 ofs << "i" << '\t' << "j" << '\t' << " << 296 "i\tj\tk\t"; 341 G4cout << "i" << '\t' << "j" << '\t' < << 297 // Total dose 342 << 298 ofs << std::setw(width) << "Dose(MeV/g)"; 343 // Total dose << 299 if (secondary) 344 ofs <<'\t' <<"Dose(Gy)"; << 300 { 345 //ofs << std::setw(width) << "Dose(Gy) << 301 for (size_t l=0; l < ionStore.size(); l++) 346 G4cout << '\t' << "Dose(Gy)"; << 302 { 347 << 303 G4String a = (ionStore[l].isPrimary) ? "_1":""; // is it a primary? 348 G4String fluence = "_f"; << 304 ofs << std::setw(width) << ionStore[l].name + a << 349 if (secondary) << 305 std::setw(width) << ionStore[l].name + a; 350 { << 306 } 351 for (size_t l=0; l < ionStore.size << 307 ofs << G4endl; 352 { << 308 353 G4String a = (ionStore[l].isPr << 309 /* 354 << 310 * PDGencondig 355 // ofs << std::setw(width) << i << 311 */ 356 // std::setw(width) << i << 312 /* 357 << 313 ofs << std::setprecision(6) << std::left << 358 ofs << '\t' << ionStore[l].nam << 314 "0\t0\t0\t"; 359 '\t' << ionStore[l]. << 315 360 << 316 // Total dose 361 G4cout << '\t' << ionStore[l]. << 317 ofs << std::setw(width) << '0'; 362 '\t' << ionStore[l]. << 318 for (size_t l=0; l < ionStore.size(); l++) 363 << 319 { 364 } << 320 ofs << std::setw(width) << ionStore[l].PDGencoding << 365 //ofs << G4endl; << 321 std::setw(width) << ionStore[l].PDGencoding; 366 } << 322 } 367 << 323 ofs << G4endl; 368 // Write data << 324 */ 369 for(G4int i = 0; i < numberOfVoxelAlon << 325 } 370 for(G4int j = 0; j < numberOfVoxel << 326 // Write data 371 for(G4int k = 0; k < numberOfV << 327 for(G4int i = 0; i < numberOfVoxelAlongX; i++) 372 { << 328 for(G4int j = 0; j < numberOfVoxelAlongY; j++) 373 G4int n = Index(i, j, k); << 329 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) 374 << 330 { 375 if (matrix[n]) << 331 G4int n = Index(i, j, k); 376 { << 332 // Write only not identically null data lines 377 ofs << G4endl; << 333 if (matrix[n]) 378 ofs << i << '\t' << j << 334 { 379 << 335 ofs << G4endl; 380 // Total dose << 336 ofs << i << '\t' << j << '\t' << k << '\t'; 381 //ofs << std::setw(wid << 337 // Total dose 382 ofs << (matrix[n]/mass << 338 ofs << std::setw(width) << matrix[n]/massOfVoxel/doseUnit; 383 << 339 if (secondary) 384 if (secondary) << 340 { 385 { << 341 for (size_t l=0; l < ionStore.size(); l++) 386 for (size_t l=0; l << 342 { 387 { << 343 // Fill ASCII file rows 388 // Fill ASCII << 344 ofs << std::setw(width) << ionStore[l].dose[n]/massOfVoxel/doseUnit << 389 //ofs << std:: << 345 std::setw(width) << ionStore[l].fluence[n]; 390 // std:: << 346 } 391 << 347 } 392 ofs << '\t' < << 348 } 393 '\t' << i << 349 } 394 } << 350 ofs.close(); 395 } << 351 } 396 } << 352 } 397 } << 353 ///////////////////////////////////////////////////////////////////////////// 398 ofs.close(); << 354 399 } << 355 #ifdef G4ANALYSIS_USE_ROOT 400 } << 356 void HadrontherapyMatrix::StoreDoseFluenceRoot() 401 ////////////////////////////////////////////// << 402 void HadrontherapyMatrix::Fill(G4int i, G4int << 403 G4double energy << 404 { 357 { 405 if (matrix) << 358 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); 406 matrix[Index(i,j,k)] += energyDeposit; << 359 if (analysis -> IsTheTFile()) >> 360 { >> 361 for(G4int i = 0; i < numberOfVoxelAlongX; i++) >> 362 for(G4int j = 0; j < numberOfVoxelAlongY; j++) >> 363 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) >> 364 { >> 365 G4int n = Index(i, j, k); >> 366 for (size_t l=0; l < ionStore.size(); l++) >> 367 >> 368 { >> 369 // Do the same work for .root file: fill dose/fluence ntuple >> 370 analysis -> FillVoxelFragmentTuple( i, j, k, >> 371 ionStore[l].A, >> 372 ionStore[l].Z, >> 373 ionStore[l].dose[n]/massOfVoxel/doseUnit, >> 374 ionStore[l].fluence[n] ); 407 375 408 // Store the energy deposit in the matrix << 409 // to the phantom voxel << 410 } << 411 376 >> 377 } >> 378 } >> 379 } >> 380 } >> 381 #endif 412 382 >> 383 void HadrontherapyMatrix::Fill(G4int i, G4int j, G4int k, >> 384 G4double energyDeposit) >> 385 { >> 386 if (matrix) >> 387 matrix[Index(i,j,k)] += energyDeposit; >> 388 >> 389 // Store the energy deposit in the matrix element corresponding >> 390 // to the phantom voxel >> 391 } >> 392 void HadrontherapyMatrix::TotalEnergyDeposit() >> 393 { >> 394 // Convert energy deposited to dose. >> 395 // Store the information of the matrix in a ntuple and in >> 396 // a 1D Histogram 413 397 >> 398 HadrontherapyAnalysisManager* analysis = HadrontherapyAnalysisManager::GetInstance(); >> 399 if (matrix) >> 400 { >> 401 for(G4int i = 0; i < numberOfVoxelAlongX; i++) >> 402 for(G4int j = 0; j < numberOfVoxelAlongY; j++) >> 403 for(G4int k = 0; k < numberOfVoxelAlongZ; k++) >> 404 { >> 405 G4int n = Index(i,j,k); >> 406 #ifdef G4ANALYSIS_USE_ROOT >> 407 if (analysis -> IsTheTFile() ) >> 408 { >> 409 analysis -> FillEnergyDeposit(i, j, k, matrix[n]/massOfVoxel/doseUnit); >> 410 analysis -> BraggPeak(i, matrix[n]/massOfVoxel/doseUnit); >> 411 } >> 412 #endif >> 413 } >> 414 } >> 415 } 414 416 415 417